From ac1f4ddf856931d6b92261fd6fba1db55f66c0e5 Mon Sep 17 00:00:00 2001 From: Werner Schweer Date: Sat, 5 Jul 2008 13:03:01 +0000 Subject: updates --- muse/CMakeLists.txt | 14 +- muse/ChangeLog | 2 + muse/doc/CMakeLists.txt | 24 - muse/doc/dimpl.odt | Bin 0 -> 37053 bytes muse/doc/dimpl/CMakeLists.txt | 41 -- muse/doc/dimpl/dimpl.tex | 865 ---------------------- muse/doc/man/de/CMakeLists.txt | 52 -- muse/doc/man/de/automation.tex | 33 - muse/doc/man/de/figurepath.tex.in | 2 - muse/doc/man/de/installation.tex | 63 -- muse/doc/man/de/man-de.tex | 413 ----------- muse/doc/man/de/midirecording.tex | 119 --- muse/doc/man/de/miditracks.tex | 132 ---- muse/doc/man/de/projekte.tex | 102 --- muse/doc/man/de/struktur.tex | 43 -- muse/doc/manual-de.odt | Bin 0 -> 50551 bytes muse/muse/CMakeLists.txt | 25 +- muse/muse/arranger.cpp | 1382 +++++++++++++++++++++++++++++++++++ muse/muse/arranger.h | 175 +++++ muse/muse/arranger/CMakeLists.txt | 60 -- muse/muse/arranger/arranger.cpp | 1382 ----------------------------------- muse/muse/arranger/arranger.h | 175 ----- muse/muse/arranger/canvas.cpp | 1187 ------------------------------ muse/muse/arranger/canvas.h | 124 ---- muse/muse/arranger/configtrack.cpp | 265 ------- muse/muse/arranger/configtrack.h | 61 -- muse/muse/arranger/configtrack.ui | 299 -------- muse/muse/arranger/midiportinfo.ui | 92 --- muse/muse/arranger/miditrackinfo.ui | 292 -------- muse/muse/arranger/partdrag.cpp | 199 ----- muse/muse/arranger/partdrag.h | 69 -- muse/muse/arranger/selectfilter.h | 51 -- muse/muse/arranger/tllineedit.cpp | 70 -- muse/muse/arranger/tllineedit.h | 48 -- muse/muse/arranger/tlswidget.cpp | 355 --------- muse/muse/arranger/tlswidget.h | 83 --- muse/muse/arranger/tlwidget.cpp | 641 ---------------- muse/muse/arranger/tlwidget.h | 105 --- muse/muse/arranger/tlwlayout.cpp | 144 ---- muse/muse/arranger/tlwlayout.h | 51 -- muse/muse/arranger/trackdrag.cpp | 61 -- muse/muse/arranger/trackdrag.h | 42 -- muse/muse/arranger/trackinfo.cpp | 553 -------------- muse/muse/arranger/trackinfo.h | 203 ----- muse/muse/arranger/trelement.h | 64 -- muse/muse/canvas.cpp | 1187 ++++++++++++++++++++++++++++++ muse/muse/canvas.h | 124 ++++ muse/muse/configtrack.cpp | 265 +++++++ muse/muse/configtrack.h | 61 ++ muse/muse/configtrack.ui | 299 ++++++++ muse/muse/importmidi.cpp | 2 +- muse/muse/jack.cpp | 25 +- muse/muse/midiportinfo.ui | 92 +++ muse/muse/miditrackinfo.ui | 292 ++++++++ muse/muse/mstrip.cpp | 76 +- muse/muse/mstrip.h | 3 +- muse/muse/muse.cpp | 2 +- muse/muse/partdrag.cpp | 199 +++++ muse/muse/partdrag.h | 69 ++ muse/muse/preferences.cpp | 2 +- muse/muse/selectfilter.h | 51 ++ muse/muse/seqmsg.cpp | 2 +- muse/muse/song.cpp | 21 +- muse/muse/songfile.cpp | 2 +- muse/muse/strip.h | 3 +- muse/muse/tllineedit.cpp | 70 ++ muse/muse/tllineedit.h | 48 ++ muse/muse/tlswidget.cpp | 355 +++++++++ muse/muse/tlswidget.h | 83 +++ muse/muse/tlwidget.cpp | 641 ++++++++++++++++ muse/muse/tlwidget.h | 105 +++ muse/muse/tlwlayout.cpp | 144 ++++ muse/muse/tlwlayout.h | 51 ++ muse/muse/trackdrag.cpp | 61 ++ muse/muse/trackdrag.h | 42 ++ muse/muse/trackinfo.cpp | 553 ++++++++++++++ muse/muse/trackinfo.h | 203 +++++ muse/muse/trelement.h | 63 ++ muse/muse/wave.cpp | 16 +- 79 files changed, 6682 insertions(+), 8693 deletions(-) delete mode 100644 muse/doc/CMakeLists.txt create mode 100644 muse/doc/dimpl.odt delete mode 100644 muse/doc/dimpl/CMakeLists.txt delete mode 100644 muse/doc/dimpl/dimpl.tex delete mode 100644 muse/doc/man/de/CMakeLists.txt delete mode 100644 muse/doc/man/de/automation.tex delete mode 100644 muse/doc/man/de/figurepath.tex.in delete mode 100644 muse/doc/man/de/installation.tex delete mode 100644 muse/doc/man/de/man-de.tex delete mode 100644 muse/doc/man/de/midirecording.tex delete mode 100644 muse/doc/man/de/miditracks.tex delete mode 100644 muse/doc/man/de/projekte.tex delete mode 100644 muse/doc/man/de/struktur.tex create mode 100644 muse/doc/manual-de.odt create mode 100644 muse/muse/arranger.cpp create mode 100644 muse/muse/arranger.h delete mode 100644 muse/muse/arranger/CMakeLists.txt delete mode 100644 muse/muse/arranger/arranger.cpp delete mode 100644 muse/muse/arranger/arranger.h delete mode 100644 muse/muse/arranger/canvas.cpp delete mode 100644 muse/muse/arranger/canvas.h delete mode 100644 muse/muse/arranger/configtrack.cpp delete mode 100644 muse/muse/arranger/configtrack.h delete mode 100644 muse/muse/arranger/configtrack.ui delete mode 100644 muse/muse/arranger/midiportinfo.ui delete mode 100644 muse/muse/arranger/miditrackinfo.ui delete mode 100644 muse/muse/arranger/partdrag.cpp delete mode 100644 muse/muse/arranger/partdrag.h delete mode 100644 muse/muse/arranger/selectfilter.h delete mode 100644 muse/muse/arranger/tllineedit.cpp delete mode 100644 muse/muse/arranger/tllineedit.h delete mode 100644 muse/muse/arranger/tlswidget.cpp delete mode 100644 muse/muse/arranger/tlswidget.h delete mode 100644 muse/muse/arranger/tlwidget.cpp delete mode 100644 muse/muse/arranger/tlwidget.h delete mode 100644 muse/muse/arranger/tlwlayout.cpp delete mode 100644 muse/muse/arranger/tlwlayout.h delete mode 100644 muse/muse/arranger/trackdrag.cpp delete mode 100644 muse/muse/arranger/trackdrag.h delete mode 100644 muse/muse/arranger/trackinfo.cpp delete mode 100644 muse/muse/arranger/trackinfo.h delete mode 100644 muse/muse/arranger/trelement.h create mode 100644 muse/muse/canvas.cpp create mode 100644 muse/muse/canvas.h create mode 100644 muse/muse/configtrack.cpp create mode 100644 muse/muse/configtrack.h create mode 100644 muse/muse/configtrack.ui create mode 100644 muse/muse/midiportinfo.ui create mode 100644 muse/muse/miditrackinfo.ui create mode 100644 muse/muse/partdrag.cpp create mode 100644 muse/muse/partdrag.h create mode 100644 muse/muse/selectfilter.h create mode 100644 muse/muse/tllineedit.cpp create mode 100644 muse/muse/tllineedit.h create mode 100644 muse/muse/tlswidget.cpp create mode 100644 muse/muse/tlswidget.h create mode 100644 muse/muse/tlwidget.cpp create mode 100644 muse/muse/tlwidget.h create mode 100644 muse/muse/tlwlayout.cpp create mode 100644 muse/muse/tlwlayout.h create mode 100644 muse/muse/trackdrag.cpp create mode 100644 muse/muse/trackdrag.h create mode 100644 muse/muse/trackinfo.cpp create mode 100644 muse/muse/trackinfo.h create mode 100644 muse/muse/trelement.h diff --git a/muse/CMakeLists.txt b/muse/CMakeLists.txt index 3712f50d..2286d40b 100644 --- a/muse/CMakeLists.txt +++ b/muse/CMakeLists.txt @@ -92,16 +92,6 @@ endif (NOT QT4_FOUND) include(${QT_USE_FILE}) -## -## find texexec (ConTeXt) -## - -find_path( TEXEXEC_PATH texutil ) -if (NOT TEXEXEC_PATH) - message("texexec from ConTeXt package not found. Documentation will not be build") -endif (NOT TEXEXEC_PATH) - - ## ## find doxygen ## TODO @@ -209,6 +199,8 @@ endif (NOT JACK_INCDIR) ## ## check for dssi +## dssi >= 0.9.0 +## liblo >= 0.23 ## if (ENABLE_DSSI) @@ -339,5 +331,5 @@ IF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake") INCLUDE(CPack) ENDIF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake") -subdirs(al awl grepmidi plugins midiplugins muse share synti doc) +subdirs(al awl grepmidi plugins midiplugins muse share synti) diff --git a/muse/ChangeLog b/muse/ChangeLog index dc8f38a3..d02cd328 100644 --- a/muse/ChangeLog +++ b/muse/ChangeLog @@ -1,3 +1,5 @@ +5.7. (ws) + - fix midi metronome output routing 29.6. (ws) - fix sending proper note off's at stop 27.6. (ws) diff --git a/muse/doc/CMakeLists.txt b/muse/doc/CMakeLists.txt deleted file mode 100644 index 387df934..00000000 --- a/muse/doc/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -#============================================================================= -# MusE -# Linux Music Editor -# $Id:$ -# -# Copyright (C) 2002-2006 by Werner Schweer and others -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2. -# -# This program 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 this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -#============================================================================= - -if (TEXEXEC_PATH) - subdirs( dimpl man ) -endif (TEXEXEC_PATH) - diff --git a/muse/doc/dimpl.odt b/muse/doc/dimpl.odt new file mode 100644 index 00000000..e62ccd90 Binary files /dev/null and b/muse/doc/dimpl.odt differ diff --git a/muse/doc/dimpl/CMakeLists.txt b/muse/doc/dimpl/CMakeLists.txt deleted file mode 100644 index 9611881e..00000000 --- a/muse/doc/dimpl/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -#============================================================================= -# MusE -# Linux Music Editor -# $Id:$ -# -# Copyright (C) 2002-2006 by Werner Schweer and others -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2. -# -# This program 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 this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -#============================================================================= - -set (SRC dimpl.tex) - -add_custom_target ( - dimpl - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/dimpl.tex - COMMAND ${TEXEXEC_PATH}/texexec - ARGS --language=en --verbose --batch --pdf - --result=dimpl.pdf - ${CMAKE_CURRENT_SOURCE_DIR}/dimpl.tex - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - ) - -install_files ( /share/${MusE_INSTALL_NAME}/doc/ .pdf - ${CMAKE_CURRENT_BINARY_DIR}/dimpl.pdf ) - -set (extraClean dimpl.log dimpl.tmp dimpl.tuo dimpl.tui - dimpl-mpgraph.mp mpgraph.mp ) - -set_directory_properties( PROPERTIES - ADDITIONAL_MAKE_CLEAN_FILES "${extraClean}" - ) diff --git a/muse/doc/dimpl/dimpl.tex b/muse/doc/dimpl/dimpl.tex deleted file mode 100644 index da5ea6c6..00000000 --- a/muse/doc/dimpl/dimpl.tex +++ /dev/null @@ -1,865 +0,0 @@ -%==================================================================== -% Muse -% Design & Implementation -% -% (C) 2005 Copyright: Werner Schweer and Others -%==================================================================== - -%---------------------------------------------------------- -% Setup -%---------------------------------------------------------- - -%\showframe -%\showsetups -\usemodule[chart] -\setupcolors[state=start] -\setupbodyfont[Palatino] -\language[en] -\enableregime[il1] - -\startuseMPgraphic{FunnyFrame} - picture p; numeric o; path a, b; pair c; - p := textext.rt(\MPstring{FunnyFrame}); - o := BodyFontSize; - a := unitsquare xyscaled(OverlayWidth,OverlayHeight); - p := p shifted (20, OverlayHeight-ypart center p); - drawoptions (withpen pencircle scaled 1pt withcolor .625red); - b := a superellipsed .95; - fill b withcolor .85white; draw b; - b := (boundingbox p) superellipsed .95; - fill b withcolor .85white; draw b; - draw p withcolor black; - setbounds currentpicture to a; - \stopuseMPgraphic - -\defineoverlay[FunnyFrame][\useMPgraphic{FunnyFrame}] -\defineframedtext[FunnyText][frame=off,background=FunnyFrame] -\def\StartFrame{\startFunnyText} -\def\StopFrame{\stopFunnyText} -\def\FrameTitle#1% - {\setMPtext{FunnyFrame}{\hbox spread 1em{\hss\strut#1\hss}}} -\setMPtext{FunnyFrame}{} - - -\define\M{Muse} -\define[1]\Index{{\it #1}\marginpar{#1}\index{#1}} - -\defineindenting[Cmdi][text=,separator=,width=fit,distance=1em] - -\define[1]\Cmd{ - \Cmdi - \framed[ - background=color, - width=fit, - align=right, - backgroundcolor=lightgray, - framecolor=blue] - {\tt\space #1}} - -\define[2]\CCmd{ - \Cmdi - \framed[ - background=color, - width=broad, - align=right, - backgroundcolor=lightgray, - framecolor=blue] - {\vbox{\hbox{\tt\space #1}\hbox{\tt\space #2}}}} - -%\define\startdescription{\startpacked} -\define\startdescription{} -%\define\stopdescription{\stoppacked} -\define\stopdescription{} - -\define[1]\Fig{\hbox{\externalfigure[pics/#1]}} - -\define[2]\Screen{ - \placefigure[here][fig:#1]{#2}{\externalfigure[pics/#1][scale=1600]} - } - -\definedescription[Option][ - location=left, - headstyle=bold, - width=4em, - before={\startnarrower[left]\setupblank[0pt]}, - after={\stopnarrower\setupblank}] - -\definedescription[Filetype][ - location=left, - headstyle=bold, - width=4em, - before={\startnarrower[left]\setupblank[0pt]}, - after={\stopnarrower\setupblank}] - -\definedescription[FileList][ - location=left, - headstyle=bold, - width=7em, - before={\startnarrower[left]\setupblank[0pt]}, - after={\stopnarrower\setupblank}] - -\definedescription[Input][ - location=left, - headstyle=bold, - width=9em, - before={\startnarrower[left]\setupblank[0pt]}, - after={\stopnarrower\setupblank}] - -\definedescription[InputN][ - location=left, - headstyle=bold, - width=6em, - before={\startnarrower[left]\setupblank[0pt]}, - after={\stopnarrower\setupblank}] - -\define[2]\Figure{ - \placefigure - [#1][fig:#2]{} - {\externalfigure[pics/#2]} - } - -\define[1]\Menu{ - \placefigure[right][fig:#1]{} - {\externalfigure[pics/#1][scale=2000]} - } - -\definedescription[Opt][location=hanging,headstyle=bold,width=broad] - -\setuptyping[before=\blank\startbackground, after=\stopbackground\blank] % source code with background -\setupwhitespace[medium] - -%---------------------------------------------------------- -% Body -%---------------------------------------------------------- - -\starttext - \language[en] - \mainlanguage[en] - \startstandardmakeup[doublesided=no] - \definebodyfont[10pt,11pt,12pt][rm][tfe=Regular at 48pt] - \tfe\setupinterlinespace - \hfill \color[red]{\M}\par - \hfill \color[blue]{Design \&}\par - \hfill \color[blue]{Implementation}\par - \vfill - \definebodyfont[10pt,11pt,12pt][rm][tfb=Regular at 24pt] - \tfb\setupinterlinespace - \hfill Version 1.0\par -%% \hfill April 2005\par -%% \hfill Werner Schweer - \stopstandardmakeup - - \startstandardmakeup[page=no] - \vfill - \M\ is hosted on SourceForge:\par - \type{http://lmuse.sourceforge.net/} - \blank[line] - This document was created using \pdfTeX\ and the - \ConTeXt\ macro package. - \blank[line] - \copyright 2005 Werner Schweer and Others - \stopstandardmakeup - - \completecontent - -%% -%%======================================================================= -%% File Formats -%%======================================================================= -%% - -\chapter{Process Structure} - -\chapter{Song} - \section{Multithreading} - - \section{Editing} - \subsection{Realtime Editing} - \M\ allows for realtime editing. That means that you can edit - a song while the sequencer is running. - Two threads want to access data in the main {\tt Song()} class: - the GUI thread and the realtime sequencer thread. - - This are the rules how \M\ handles {\tt Song()} data accesses: - - \startitemize[packed,broad] - \item the GUI thread can only read {\tt Song()} data - \item the GUI thread can request the sequencer thread to - modify Song data - \item the sequencer thread can modify {\tt Song()} data, but only - on request of the GUI thread - \stopitemize - - Interprocess communication is done via message passing. - Communication from the gui thread to the sequencer thread is - done in the following steps: - - \startitemize[packed,broad] - \item the GUI sends a Message to the sequencer thread - and waits for an answer - \item once the sequencer thread is running (the JACK - client {\tt process()} call) it processes the message and - sends back an answer to the GUI process. - \item the GUI process reads the answer and continues - \stopitemize - - This scheme stops the GUI process in a defined state while the - realtime process can safely manipulate the {\tt Song()} data. - - \subsection{User Transaction} - - A user transaction is a sequence of actions manipulating the - main {\tt Song()} structure. Each action involves sending a - message to the realtime thread. This means that every action - stops the GUI thread for at most one JACK cycle. - - If a transaction consists of lot of actions then this scheme - would be too slow. For such cases the sequencer thread is switched - to "idle" mode, which ensures it is not touching the {\tt Song()} - data anymore. Then safe manipulation of the data is possible. - - \subsection{Naming Conventions} - - There are several methods involved in an edit transaction; - example for adding a part: - - \startitemize[packed,broad] - \item {\tt cmdAddPart()} - This implements a complete undoable user transaction - and is called from the gui thread - \item {\tt addPart()} - This method is also called from the gui thread. It - implements part of a user transaction. It is not - surrounded by {\tt startUndo() endUndo()}. - \item the realtime part (actually removing the {\tt Part} from the - PartList) is done inline during processing of - messages in the sequencer thread. - \stopitemize - - -\chapter{File Formats} - \section{Instrument Definition Files} - - \M\ Instrument Definition Files are used to describe the - properties of external midi instruments. - - IDF-Files have the file extension \type{*.idf} \index{idf} and - they are searched in the \M\ "instruments" subdirectory (which is on - my system \type{/usr/share/muse-1.0/instruments}. - - An instrument definition file should only define one - instrument. - - An instrument\index{Instrument definition} is a property of the - midi channel \index{Midi channel}. - All found instrument definitions are presented by MusE - in the Instrument pulldown menu of the midi output port. - - Example of an instrument definition file: - \blank - -\starttyping - - - - - ...MusE event list which initializes instrument - - - - - ... - - - - - Clave - 24 - 24 - - - SdBrMtSt - 25 - 25 - - ... - - - - - - - - ... - - ... - - -\stoptyping - - \blank - - \subsection{Init Sequence} - The {\tt Init} section declares a list of midi events to initialize - the instrument. The section can be empty or absent. - - \subsection{Patch Groups} - Patch Groups are used to structure the list of patches. - PatchGroups\index{PatchGroups} are not mandatory; its valid to write: - - \blank -\starttyping - - - - - - ... - -\stoptyping - \blank - - \subsection{Patches} - - The "prog" parameter in a "Patch" is mandatory. Missing - "hbank" or "lbank" are treated as "don't care". - Missing "drum" is treated as drum="0". - - A XG-Patch looks like this: - - \blank - \starttyping - - \stoptyping - \blank - - A patch can be associated with a "mode" with one of: - \blank[medium] - \Option{1} - GM\par - \Option{2} - GS\par - \Option{4} - XG\par - \blank[big] - - Example: - - \blank - \starttyping - - \stoptyping - \blank - - Mode id's can be ore'd together for patches which are valid - for more than one mode: - - \blank - \starttyping - - \stoptyping - \blank - - example for MusE event (Sysex "XG-On"): - - \blank - \starttyping - - 43 10 4c 00 00 7e 00 - - \stoptyping - \blank - - \type{ ... } part can be omitted - - \subsection{Drum Maps} - A drum map allows to define properties for every note in a patch. - The {\tt drummap} entry looks like the {\tt Patch} entry and defines - the banks and the program number for the drummap. - - \subsection{Controller} - Controller \index{Controller} have the following properties: - - \starttabulate - \NC name:\NC - arbitrary unique (short) string describing the controller\NC\NR - \NC n:\NC - controller number, defines also the controller type:\par - values from \type{0x0 - 0x7f} are 7Bit controller\par - values from \type{0x1000 - 0x1ffff} are 14 bit controller with - MSB/LSB value pairs\par - values from \type{0x20000 - 0x2ffff} are RPN's\par - values from \type{0x30000 - 0x3ffff} are NRPN's - \NC\NR - \NC min:\NC minimum value for controller\NC\NR - \NC max:\NC maximum value for controller\NC\NR - \NC init:\NC - reset value for controller; when controller value is - undefined after instrument reset, use the ''undefined'' - value \type{0x10000} - \NC\NR - \stoptabulate - - the min/max/init values can be ommited - -%% -%%======================================================================= -%% Midi Plugins -%%======================================================================= -%% -\chapter{Plugins} - \section{Midi Plugins} - - - Midi plugins have the file extension \type{*.so} and they are - searched in the \M\ "{\tt midiplugins} subdirectory (which is on - my system \type{/usr/lib/muse-1.0/midiplugins}. - -% -%----------------------------------- -% Midi Filter -%----------------------------------- -% - \subsection{Midi Filter} - - Example for an midi plugin which does essentially nothing: - - First define your custom \type{Filter} class with \type{Mempi} - as base class. - -\starttyping -#include "../libmidiplugin/mempi.h" - -class Filter : public Mempi { - virtual void process(unsigned, unsigned, - MPEventList*, MPEventList*); - - public: - Filter(const char* name, const MempiHost*); - ~Filter() {} - virtual bool init() { return false; } - }; - -Filter::Filter(const char* name, const MempiHost* h) - : Mempi(name, h) - { - } -\stoptyping - - Now comes the main \type{Mempi} function you have to implement: - \type{process()} which has two parameters, an midi event input - list and an midi event output list. The example code simply - copies all events from the input list to the output list. - -\starttyping -void Filter::process(unsigned, unsigned, MPEventList* il, - MPEventList* ol) - { - for (iMPEvent i = il->begin(); i != il->end(); ++i) { - ol->insert(*i); - } - } -\stoptyping - - When loading the plugin, the \type{Mempi} Host looks for - the symbol \type{mempi_descriptor}. This function returns a - pointer to the plugin class description you have to fill in. - -\starttyping -static Mempi* instantiate(const char* name, const MempiHost* h) - { - return new Filter(name, h); - } - -extern "C" { - static MEMPI descriptor = { - "Filter", - "MusE Zero Filter", - "0.1", // filter version string - MEMPI_FILTER, // plugin type - MEMPI_MAJOR_VERSION, MEMPI_MINOR_VERSION, - instantiate - }; - - const MEMPI* mempi_descriptor() { return &descriptor; } - } -\stoptyping - - -% -%----------------------------------- -% GUI interface -%----------------------------------- -% -\subsection{GUI interface} - Every midi plugin can implement a native graphical user - interface (GUI). For this you have to overload five - virtual functions. - -\starttyping - virtual bool hasGui() const { return true; } -\stoptyping - This function informs the host whether there is an GUI or not. - -\starttyping - virtual bool guiVisible() const { return gui->isVisible(); } -\stoptyping - This fuction returns \type{true} if your GUI is visible. - -\starttyping - virtual void showGui(bool val) const { gui->setShown(val); } -\stoptyping - This function shows or hides the GUI. - - There are two helper functions the plugin host uses to save - and restore the GUI geometry across sessions: - -\starttyping - virtual void getGeometry(int* x, int* y, int* w, int* h) const; - virtual void setGeometry(int, int, int, int); -\stoptyping - -% -%----------------------------------- -% Persistent Parameters -%----------------------------------- -% -\subsection{Persistent Parameters} - - The plugin host can save and restore plugin parameter across - sessions. When the host saves his session status, he calls - the midi plugin function: - -\starttyping - virtual void getInitData(int* len, const unsigned char**p) const; -\stoptyping - - You can overload this function to return a pointer to your - session data and the len of the data block. - - When the session is restored, the host calls - -\starttyping - virtual void setInitData(int len, const unsigned char* p); -\stoptyping - - which you can use to restore the last plugin state. -% -%----------------------------------- -% Host Access Functions -%----------------------------------- -% - -\subsection{Host Access Functions} - - The plugin host supplies some functions which are - accessible through the \type{MempiHost*} in the - \type{Mempi} interface. - - The host supplies the following functions: - -\starttyping - int division() const; -\stoptyping - \index{division()} - returns the midi \type{division} value which gives the number - of midi ticks per midi beat, typically 384. - -\starttyping - int tempo(unsigned tick) const; -\stoptyping - \index{tempo()} - returns the midi tempo value. - -\starttyping - unsigned tick2frame(unsigned tick) const; -\stoptyping - \index{tick2frame()} - This function converts a transport position given in midi ticks - to a audio frame position. - -\starttyping - unsigned frame2tick(unsigned frame) const; -\stoptyping - \index{frame2tick()} - This function converts a transport position given in audio frames - to midi ticks. - -\starttyping - void bar(int tick, int* bar, int* beat, unsigned* rest) const; -\stoptyping - \index{bar()} - This function return bar/beat and a tick rest for a given - tick position. - -\starttyping - unsigned bar2tick(int bar, int beat, int tick) const; -\stoptyping - This is the opposite to the \type{bar} function. It converts - a time position given in bar/beat/tick into a midi tick value. - -% -%----------------------------------- -% Midi Synthesizer -%----------------------------------- -% -\subsection{Midi Synthesizer} - As an example for a midi synthesizer plugin we use a midi - metronome. - - Lets start with the class definition: - -\starttyping -#include "../libmidiplugin/mempi.h" - -//--------------------------------------------------------- -// metronom - simple midi metronom -//--------------------------------------------------------- - -class Metronom : public Mempi { - - protected: - struct InitData { - char measureNote; - char measureVelo; - char beatNote; - char beatVelo; - } data; - MetronomGui* gui; - friend class MetronomGui; - - unsigned int nextTick; - unsigned int lastTo; - - virtual void process(unsigned, unsigned, MPEventList*, - MPEventList*); - - public: - Metronom(const char* name, const MempiHost*); - ~Metronom(); - virtual bool init(); - - virtual bool hasGui() const { return true; } - virtual bool guiVisible() const { return gui->isVisible(); } - virtual void showGui(bool val) { gui->setShown(val); } - virtual void getGeometry(int* x, int* y, int* w, int* h) const; - virtual void setGeometry(int, int, int, int); - - virtual void getInitData(int*, const unsigned char**) const; - virtual void setInitData(int, const unsigned char*); - }; -\stoptyping - -% -%----------------------------------- -% MESS interface -%----------------------------------- -% -\chapter {The M.E.S.S (MusE Experimental Software Synthesizer) API} - - M.E.S.S.\index{M.E.S.S.} stands for MusE Experimental Soft Synth and is - an API/interface (like DSSI) to enable programmers to easily create their - own softsynths. - - The interface for a M.E.S.S.-synth consists of two classes, the Mess and - MessGui. In short, the framework provides the Mess (the synth) midi data - (notes, controllers and sysexes) and methods that handle the IPC between - the gui and the synth, so the programmer can focus on DSP-issues instead. - - The interface for the synth is specified in the mess.h file in the libsynti - directory. The interface for the MessGui is specified in the gui.h file. - -\starttyping -//--------------------------------------------------------- -// Mess -// MusE experimental software synth -// Instance virtual interface class -//--------------------------------------------------------- - -class Mess { - MessP* d; - - int _sampleRate; - int _channels; // 1 - mono, 2 - stereo - - public: - Mess(int channels); - virtual ~Mess(); - - int channels() const { return _channels; } - int sampleRate() const { return _sampleRate; } - void setSampleRate(int r) { _sampleRate = r; } - - virtual void process(float** data, int offset, int len) = 0; - - // the synti has to (re-)implement processEvent() or provide - // some of the next three functions: - - virtual bool processEvent(const MidiEvent&); - virtual bool setController(int, int, int) { return false; } - virtual bool playNote(int, int, int) { return false; } - virtual bool sysex(int, const unsigned char*) { return false; } - - virtual void getInitData(int*, const unsigned char**) const {} - virtual int getControllerInfo(int, const char**, int*, int*, int*) - const { return 0; } - virtual const char* getPatchName(int, int, int) - const { return "?"; } - virtual const MidiPatch* getPatchInfo(int, const MidiPatch*) - const { return 0; } - - // synthesizer -> host communication - void sendEvent(MidiEvent); // called from synti - MidiEvent receiveEvent(); // called from host - int eventsPending() const; - - // GUI interface routines - virtual bool hasGui() const { return false; } - virtual bool guiVisible() const { return false; } - virtual void showGui(bool) {} - virtual void getGeometry(int* x, int* y, int* w, int* h) const; - virtual void setGeometry(int, int, int, int) {} - }; -\stoptyping - -\section{Overview of virtual member functions} - This is a short description of the virtual functions in the Mess-class: -\subsection{process} -\starttyping -virtual void process(float** data, int offset, int len) = 0; -\stoptyping - This is where the audio processing takes place. The Mess is called with a float array, and - it's up to the programmer to fill it with data beginning at data[offset] to data[offset+len]. - -\subsection{processEvent} - There are two ways to go when it comes to how midi data is fed into the Mess. You can either - implement processEvent and manage the different event types (controllers, sysexes and notes) - or implement one or more of the setController, playNote and sysex functions. - - - Note that overriding processEvent results in setController, playNote and sysex - not being called! - -\subsection{setController, playNote, sysex} - The setController, playNote and sysex functions should return false if the event was - processed, true if the synth was busy. - -\starttyping -virtual bool setController(int channel, int ctrlNo, int value) -virtual bool playNote(int channel, int pitch, int velo) -virtual bool sysex(int length, const unsigned char* data) -\stoptyping - -\subsection{getInitData} - MusE provides an interface for storing the state of the synth in the project file. - getInitData is called when the project is saved, and provides a pointer to a data - block where you store the data which will recreate the synths current state when - the project is reopened. -\starttyping -virtual void getInitData(int* nrofchars, const unsigned char** data) - const {} -\stoptyping - -\subsection{getControllerInfo} - getControllerInfo is called when the Mess is instantiated, and this is where - you tell MusE which controllers the Mess supports. The function is called - repeteadly: just fill in the values for the controller and return the index - you want to be sent next time. Return 0 when you've given MusE information about - all controllers your Mess supports. - - As you can see, the necessary parameters are an index (used internally), a name - for the controller, an int describing the actual controller number (f.ex. 91 for - reverb), and finally min and max values for the controller. - -\starttyping -virtual int getControllerInfo(int index, - const char** name, - int* controller, - int* min, - int* max) const -\stoptyping - -\subsection{hasGui} - hasGui is called when the Mess is instantiated, and tells MusE if the synth has - a gui or not. -\starttyping -virtual bool hasGui() const; -\stoptyping - -\subsection{showGui} -showGui is called from MusE when the gui is supposed to be visible -\starttyping -virtual void showGui(bool show); -\stoptyping - -\subsection{getPatchName, getPatchInfo} - getPatchName and getPatchInfo are used to give MusE information about patches, - which can be selected in the track inspector. - - The getPatchName function specifies three parameters to be passed: channel, - program, and a third that is unused. It is the responsibility for the synth - to return the patchname for the particular channel and a program. - -\starttyping -virtual const char* SimpleSynth::getPatchName(int channel, int program, - int unused) const -\stoptyping - - getPatchInfo is called repeatedly until the synth returns 0. The synth must - send information back in a MidiPatch struct. The MidiPatch parameter sent - contains information on the last MidiPatch that was sent from the synth - (a null pointer on first call). - -\starttyping -virtual const MidiPatch* getPatchInfo(int channel, - const MidiPatch* previouspatch) - const; - -struct MidiPatch { - signed char type; // 1 - GM 2 - GS 4 - XG - signed char hbank, lbank, prog; - const char* name; - }; -\stoptyping - - -\subsection{Descriptor} - Since the synths are built as shared libraries, you need to specify a descriptor - for your MESS. They look something like this: (example taken from SimpleSynth/SimpleDrums) - -\starttyping -static Mess* instantiate(int sr, const char* name) - { - printf("SimpleSynth sampleRate %d\n", sr); - SimpleSynth* synth = new SimpleSynth(sr); - if (!synth->init(name)) { - delete synth; - synth = 0; - } - return synth; - } -extern "C" - { - static MESS descriptor = { - "SimpleSynth", - "Mathias Lundgren (lunar_shuttle@users.sf.net)", - "0.1", //Version string - MESS_MAJOR_VERSION, MESS_MINOR_VERSION, - instantiate, - }; - const MESS* mess_descriptor() { return &descriptor; } - } -\stoptyping - -\section{MessGui} - For the Gui, there's really only one method that is interesting, processEvent. - processEvent in the gui is called whenever the synth sends it a midiEvent, which - it does with send(MidiEvent ). - Since this is the only method of communicating the gui can send midimessages - to the synth via sendEvent, sendController and sendSysex calls. -\starttyping -virtual void processEvent(const MidiPlayEvent&) {}; -\stoptyping - - -\completeindex -\stoptext diff --git a/muse/doc/man/de/CMakeLists.txt b/muse/doc/man/de/CMakeLists.txt deleted file mode 100644 index ac009499..00000000 --- a/muse/doc/man/de/CMakeLists.txt +++ /dev/null @@ -1,52 +0,0 @@ -#============================================================================= -# MusE -# Linux Music Editor -# $Id:$ -# -# Copyright (C) 2002-2006 by Werner Schweer and others -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2. -# -# This program 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 this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -#============================================================================= - -add_custom_target ( - manual - DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/man-de.tex - ${CMAKE_CURRENT_SOURCE_DIR}/projekte.tex - ${CMAKE_CURRENT_SOURCE_DIR}/miditracks.tex - ${CMAKE_CURRENT_SOURCE_DIR}/struktur.tex - ${CMAKE_CURRENT_SOURCE_DIR}/midirecording.tex - ${CMAKE_CURRENT_SOURCE_DIR}/installation.tex - ${CMAKE_CURRENT_SOURCE_DIR}/automation.tex - COMMAND ${TEXEXEC_PATH}/texexec - ARGS --language=en --verbose --batch --pdf - --result=man-de.pdf - ${CMAKE_CURRENT_SOURCE_DIR}/man-de.tex - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - ) - -install_files ( /share/${MusE_INSTALL_NAME}/doc/ .pdf - ${CMAKE_CURRENT_BINARY_DIR}/man-de.pdf ) - -set (extraClean man-de.log man-de.tmp man-de.tuo man-de.tui - man-de-mpgraph.mp mpgraph.mp ) - -set_directory_properties( PROPERTIES - ADDITIONAL_MAKE_CLEAN_FILES "${extraClean}" - ) - -configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/figurepath.tex.in - ${CMAKE_CURRENT_BINARY_DIR}/figurepath.tex - ) - diff --git a/muse/doc/man/de/automation.tex b/muse/doc/man/de/automation.tex deleted file mode 100644 index 36e2872b..00000000 --- a/muse/doc/man/de/automation.tex +++ /dev/null @@ -1,33 +0,0 @@ - -%% \chapter{Automation} -\section{Betriebsarten} - - In \M\ gibt es vier verschiedene Automations-Betriebsarten: - - \blank[big] - \Input{Manuell:} - Im manuellen Modus kommen Controllerveränderungen nur - vom Mixer oder ChannelInfo. Die Schieber, Regler und - Eigabefelder zeigen den aktuellen Zustand der Midigeräte. - Wird z.B. der Volume Schieber bewegt, wo werden sofort - entsprechende Midi Events zu den angeschlossenen Midigeräten - geschickt. - - \Input{Read:} - Die aktuellen Controllerwerte kommen ausschließlich von den - aufgezeichneten Controller Spuren. - Schieber und Regler des Mixers und des ChannelInfo Windows - können manuell nicht verändert werden. - - \Input{Write:} - Bei Play oder Record werden alte Controllerwerte - durch die Werte der Schieber und Regler berschrieben. - - \Input{Read/Write:} - Wird ein Schieber oder Regler angeclickt, so wird die - Automation Betriebsart bis zum ''release'' von ''read'' auf ''write'' - umgeschaltet. Alle Controllerbewegungen werden aufgezeichnet - und überschreiben alte Werte. - - \blank[big] - diff --git a/muse/doc/man/de/figurepath.tex.in b/muse/doc/man/de/figurepath.tex.in deleted file mode 100644 index 0e2f7023..00000000 --- a/muse/doc/man/de/figurepath.tex.in +++ /dev/null @@ -1,2 +0,0 @@ -\setupexternalfigures[directory={@CMAKE_SOURCE_DIR@/doc/man}] - diff --git a/muse/doc/man/de/installation.tex b/muse/doc/man/de/installation.tex deleted file mode 100644 index 4b45531c..00000000 --- a/muse/doc/man/de/installation.tex +++ /dev/null @@ -1,63 +0,0 @@ -%% \chapter{Installation} - \section{Tips für Ubuntu/Kubuntu} - - \subsection{Alsa-Sequencer} - - \M\ benötigt das ALSA Sequencer Modul. Dies wird von Ubuntu leider - beim Systemstart nicht installiert. - - Wir können das aber leicht durch einen Eintrag in {\tt /etc/modules} - beheben: - - \starttyping - sudo bash - modprobe snd-seq - echo snd-seq >> /etc/modules - \stoptyping - - (Nachtrag: im aktuellen Ubuntu 04.07 ("festy") wird das Sequencer - Modul standardmäßig geladen) - - \subsection{Realtime Clock} - - Normalen Programmen ist der Zugriff auf die Echtzeituhr - (RTC = "realtime clock") von Linux - verwehrt. \M\ benötigt jedoch eine genaue Uhr, um ein exaktes - Miditiming erzeugen zu können. - Zunächst wollen wir daher die RTC für alle Audioprogrammen - verfügbar machen: - - \starttyping - sudo chown -vv root:audio /dev/rtc - sudo chmod g+rw /dev/rtc - \stoptyping - - Jetzt haben alle Programme der audio Gruppe Zugriff auf die - RTC, dürfen jedoch noch nicht die hohen von \M\ benötigten - Auflösungen einstellen. - Um dies zu Erlauben geben wir ein: - - \starttyping - sudo bash - echo 1024 > /proc/sys/dev/rtc/max-user-freq - echo dev.rtc.max-user-freq=1024 >> /etc/sysctl.conf - \stoptyping - - Durch den Eintrag in der Datei {\tt /etc/sysctl.conf} erfolgt diese - Einstellung nun auch nach jedem Systemstart. - - \subsection{Realtime Rechte} - - Um Prozesse mit Echtzeit Privilegien starten zu können ergänzen - wir die Datei {\tt /etc/security/limits.conf} um folgende Zeilen: - - \starttyping - @audio - rtprio 99 - @audio - memlock 200000 - @audio - nice -10 - \stoptyping - - \subsection{Low Latency Kernel} - \subsubsection{Interrupt Thread Prioritäten} - - diff --git a/muse/doc/man/de/man-de.tex b/muse/doc/man/de/man-de.tex deleted file mode 100644 index 2269e25a..00000000 --- a/muse/doc/man/de/man-de.tex +++ /dev/null @@ -1,413 +0,0 @@ -%==================================================================== -% MusE Manual -% dies ist das MusE Manual -% -% (C) 2006 Copyright: Werner Schweer und Andere -%==================================================================== - -%---------------------------------------------------------- -% Setup -%---------------------------------------------------------- - -%\showframe -%\showsetups -\usemodule[chart] -\setupcolors[state=start] -\setupbodyfont[Palatino] -\language[de] - -% typeset in unicode (utf8) -% \enableregime[il1] -\enableregime[utf] - -\startuseMPgraphic{FunnyFrame} - picture p; numeric o; path a, b; pair c; - p := textext.rt(\MPstring{FunnyFrame}); - o := BodyFontSize; - a := unitsquare xyscaled(OverlayWidth,OverlayHeight); - p := p shifted (20, OverlayHeight-ypart center p); - drawoptions (withpen pencircle scaled 1pt withcolor .625red); - b := a superellipsed .95; - fill b withcolor .85white; draw b; - b := (boundingbox p) superellipsed .95; - fill b withcolor .85white; draw b; - draw p withcolor black; - setbounds currentpicture to a; - \stopuseMPgraphic - -\defineoverlay[FunnyFrame][\useMPgraphic{FunnyFrame}] -\defineframedtext[FunnyText][frame=off,background=FunnyFrame] -\def\StartFrame{\startFunnyText} -\def\StopFrame{\stopFunnyText} -\def\FrameTitle#1% - {\setMPtext{FunnyFrame}{\hbox spread 1em{\hss\strut#1\hss}}} -\setMPtext{FunnyFrame}{} - - -\define\M{MusE} -\define[1]\Index{{\it #1}\marginpar{#1}\index{#1}} - -\defineindenting[Cmdi][text=,separator=,width=fit,distance=1em] - -\define[1]\Cmd{ - \Cmdi - \framed[ - background=color, - width=fit, - align=right, - backgroundcolor=lightgray, - framecolor=blue] - {\tt\space #1}} - -\define[2]\CCmd{ - \Cmdi - \framed[ - background=color, - width=broad, - align=right, - backgroundcolor=lightgray, - framecolor=blue] - {\vbox{\hbox{\tt\space #1}\hbox{\tt\space #2}}}} - -%\define\startdescription{\startpacked} -\define\startdescription{} -%\define\stopdescription{\stoppacked} -\define\stopdescription{} - -\define[1]\Fig{\blank\hbox{\externalfigure[#1]}\blank} - -\define[2]\Screen{ - \placefigure[here][fig:#1]{#2}{\externalfigure[#1][scale=1600]} - } -\definedescription[Option][ - location=left, - headstyle=bold, - width=4em, - before={\startnarrower[left]\setupblank[0pt]}, - after={\stopnarrower\setupblank}] - -\definedescription[Filetype][ - location=left, - headstyle=bold, - width=6em, - before={\startnarrower[left]\setupblank[0pt]}, - after={\stopnarrower\setupblank}] - -\definedescription[FileList][ - location=left, - headstyle=bold, - width=7em, - before={\startnarrower[left]\setupblank[0pt]}, - after={\stopnarrower\setupblank}] - -\definedescription[Input][ - location=left, - headstyle=bold, - width=9em, - before={\startnarrower[left]\setupblank[0pt]}, - after={\stopnarrower\setupblank}] - -\definedescription[InputN][ - location=left, - headstyle=bold, - width=6em, - before={\startnarrower[left]\setupblank[0pt]}, - after={\stopnarrower\setupblank}] - -\define[2]\Figure{ - \placefigure - [#1][fig:#2]{} - {\externalfigure[pics/#2]} - } - -\define[1]\Menu{ - \placefigure[right][fig:#1]{} - {\externalfigure[pics/#1][scale=2000]} - } - -\definedescription[Opt][location=hanging,headstyle=bold,width=broad] - -\setuptyping[before=\blank\startbackground, after=\stopbackground\blank] % source code with background -\setupwhitespace[medium] - -\component figurepath.tex - -%---------------------------------------------------------- -% Body -%---------------------------------------------------------- - -\starttext - \language[de] - \mainlanguage[de] - \startstandardmakeup[doublesided=no] - \definebodyfont[10pt,11pt,12pt][rm][tfe=Regular at 48pt] - \tfe\setupinterlinespace - \hfill \color[red]{\M}\par - \hfill \color[blue]{Manual}\par - \vfill - \rightaligned{\externalfigure[titlelogo]} - \vfill - \hfill \color[blue]{DE}\par - \definebodyfont[10pt,11pt,12pt][rm][tfb=Regular at 24pt] - \tfb\setupinterlinespace - \hfill Version 1.0pre1\par - \stopstandardmakeup - - \startstandardmakeup[page=no] - \vfill - \M\ wird von SourceForge gehostet:\par - \type{http://sourceforge.net/projects/lmuse} - \blank[line] - Dieses Dokument wurde mit \pdfTeX\ und dem Macro Paket - \ConTeXt\ erstellt. - \blank - \copyright 2006 Werner Schweer und Andere\par - Titelgrafik \copyright Joachim Schiele - \stopstandardmakeup - - \completecontent - -\chapter{\M\ Quickstart} - \component midirecording.tex - \section{Audio Playback} - \section{Audio Recording} - -\component projekte.tex -\component struktur.tex -\component miditracks.tex - -\chapter{Automation} - \component automation.tex - -\chapter{Funktionsreferenz} - \section{Hauptfenster} - \subsection{Menüs} - Projekt - Open Project - Open Recent - Save Project - Import Midifile - Export Midifile - Import Wavefile - Quit - Edit - Undo - Redo - Cut - Copy - Paste - Delete Parts - Delete Selected Tracks - Add Track - Add Midi Track - Add Midi Output - Add Midi Input - Add Midi Generator - Add Wave Track - Add Audio Output - Add Audio Group - Add Audio Input - Add Soft Synth - Select - Select All - Deselect All - Invert Selection - Inside Loop - Outside Loop - All Parts on Track - Pianoroll - Midi Tracker - Drums - List - Master Track - Project Properties - - View - Transport Panel - Bigtime Window - Mixer 1 - Mixer 2 - Marker - - Structure - Global Cut - Global Insert - Global Split - Copy Range - Cut Events - Midi - Edit Instrument - Reset Instr. - Init Instr. - local off - Audio - Bounce To Track - Bounce To File - Restart Audio - Settings - Configure Shortcuts - Follow Song - dont follow Song - follow page - follow continuous - Midi Sync - Midi File Export - Preferences - - Help - Manual - MusE Homepage - Report Bug - About MusE - About Qt - What's This - - \subsection{Werkzeugleisten} - Project Buttons - Open - Save - Whats This - Undo - Redo - Edit Tools - Zeiger - Stift - Radiergummi - Schere - Kleber - Linientool - Mute - Transport - Loop - Punch In - Punch Out - Gehe nach Anfang - Zurückspulen - Vorspulen - Stop - Play - Record - Panic - Arranger - Cursor - Snap - Len - Pitch - Tempo - 50% - N - 200% - Trackliste - Einstellungen - m global Mute - s global Solo - aR global AutomationRead - aW global AutomationWrite - - Info Button - Mixer Button - - \subsection{Trackliste} - Midi Input - Midi Output - Midi Track - Midi Synthesizer - Audio Track - Audio Input - Audio Output - Audio Group - Audio Synthesizer - - \subsection{Arranger} - Lineal - Marker - Locator - - - \section{Globale Editor Funktionen} - \subsection{Globaler Schnitt} - Die ''Globaler Schnitt''-Funktion enfernt auf allen Spuren den Bereich - zwischen der linken und rechten Marke. Nachfolgende Events rücken - dabei auf. Auch Markerposition und Tempoevents werden - verschoben. Lediglich stumm geschaltete Spuren werden nicht - berücksichtigt. - - \subsection{Global Einfügen} - Mit der ''Global Einfügen''-Funktion kann ein leerer Bereich eingefügt - werden. Der Bereich wird an der Position des linken Markers - eingefügt. Die Dauer des eingefügten Bereichs entspricht dem Abstand - zwischen linker und rechter Marke. Marker und Tempoevents hinter der - Einfügeposition werden entsprechend verschoben. - Stumm geschaltete Spuren werden nicht verändert. - - \subsection{Global Splitten} - Die ''Global Splitten''-Funktion entspricht der Scheren-Funktion für - einzelne Parts. Im Gegensatz zur Scheren-Funktion wird jedoch nicht - ein Part, sondern alle Parts an der aktuellen Markerposition - geschnitten. Dies gilt nicht für stummgeschaltete Spuren. - - \subsection{Bereich Kopieren} - Mit der ''Global Kopieren''-Funktion können komplette Teile eines - Songs an eine andere Stelle kopiert werden: - - \startitemize[packed] - \item stellen Sie die linke Marke an den Anfang des zu kopierenden - Bereichs - \item stellen Sie die rechte Marke an das Ende des zu kopierenden - Bereichs - \item setzen Sie den Lokator an die Einfgestelle - \item wählen Sie ''Copy Range'' aus dem ''Struktur'' Menü. - \stopitemize - - Wie bei allen anderen Strukturkommandos werden stummgeschaltete - Spuren nicht berücksichtigt. - - \section{Arranger} - \subsection{Spurtypen} - \startitemize[packed] - \item Midispur - \item Audiospur - \item Midiinput - \item Midioutput - \item Midigenerator - \item Audioinput - \item Audiooutput - \item Audiogruppe - \item Software Synthesizer - \stopitemize - - \subsection{Spur Operationen} - \startitemize[packed] - \item Spur erzeugen - \item Spur löschen - \item Spur verschieben - \item Spur kopieren - \stopitemize - - \subsection{Part Operationen} - \startitemize[packed] - \item Part erzeugen - \item Part löschen - \item Part verschieben - \item Part kopieren - \item Part clonen - \item Part declonen - \item Part nach Vorne verlängern - \item Part nach Hinten verlängern - \item Part stummschalten - \item Part einfärben - \stopitemize - - \section{Pianoroll Editor} - \section{Drum Editor} - \section{Master Editor} - -\chapter{Installation} - \component installation.tex - -\startappendices - \component ../gpl.tex - \completeindex - \stopappendices -\stoptext - diff --git a/muse/doc/man/de/midirecording.tex b/muse/doc/man/de/midirecording.tex deleted file mode 100644 index c0c0e4d6..00000000 --- a/muse/doc/man/de/midirecording.tex +++ /dev/null @@ -1,119 +0,0 @@ -\section{Midi Recording} - Auf der ersten Tour werden wir mit \M\ eine Midi Spur - mit einem externen Synthesizer, einem Yamaha S90 aufnehmen. - - \subsection{Geräte verbinden} - Für den Anschluß von Midigeräten gibt es verschiedene Möglichkeiten. - - \subsubsection{Midi} - Der serielle Midi-Anschluß eines Keyboards eignet sich nicht zum - direkten Anschluß an den PC Serienport. Bei Midi handelt es sich - um eine galvanisch per Optokoppler getrennte Stromschnittstelle, - während der PC eine RS232 Schnittstelle mit 12 Volt Pegeln bedient. - Ein einfaches Umrüsten der PC-Schnittstelle mit einem Optokoppler - funktioniert nicht, da der PC die MIDI-Taktrate nicht erzeugen kann. - - Als Lösung muß ein spezielles Midi-Interface her. Meist befindet sich - eine Midi-Schnittstelle auf der Soundkarte. Doch Vorsicht, nicht - alle Midi-Schnittstellen sind gleich gut, z.B. sind einige alte - Soundblaster Modelle duch unglückliches Hardware-Design nicht in der - Lage, die volle Midi Transferrate beim Senden von Midi Daten zu - erreichen. - - \subsubsection{USB} - Viele aktuelle Midigeräte besitzen einen USB Anschluß. USB ist schnell - und flexibel und damit die Schnittstelle der Wahl. - - \subsubsection{ToHost} - Einige ältere Midigeräte bieten einen einfachen PC Anschluß über - einen normalen Serienport (''ToHost'' Schnittstelle genannt). Es - handelt sich um einen normalen RS232 Anschluß, der die PC-üblichen - Übertragungsraten versteht. - - \subsection{Neues Projekt erzeugen} - Dann kanns losgehen. Wir starten \M\ und es erscheint das - zuletzt bearbeitete Projekt so wie wir es verlassen haben. - - Um ein neues Projekt anzulegen clicken wir auf das Projekt - Icon und der Projektdialog erscheint: - - \Fig{select_project} - - Wenn \M\ zum allererstenmal gestartet wird, erscheint der - Projektdialog natürlich sofort, da es ja kein letztes Projekt - gibt. Zum Projektdialog gelangen wir auch über den Projekmenü - Eintrag ''Öffnen'' oder wer es ganz eilig hat tippt einfach - {\tt Ctrl+O}. - - In der ''Projekt'' Eingabezeile geben wir nun einen Projektnamen - für unser erstes Projekt ein und bestätigen dann durch clicken - des ''Ok'' Buttons. - - \M\ fragt nun nach einem Template, mit dem das Projekt - initialisiert werden soll: - - \Fig{select_template} - - Wir selektieren kein Template und clicken einfach ''Ok''. - \M\ zeigt dann ein leeres Projekt: - - \Fig{main0} - - \subsection{Setup} - - \subsubsection{Spuren anlegen} - - Zunächst erzeugen wir einen ''MidiInput'' Track und checken, - ob das Keyboard richtig angeschlossen ist. - - \subsubsection{Routing} - - \subsubsection{Midi Instrument} - Im ''MidiOutPort'' Strip kann ein Midi Instrument ausgewählt werden. - Dies ermöglicht es \M\ u.A. die Instrument-Patches anstatt per Nummer - per Name anzuzeigen. Instrumente werden in einer ''{\tt *.idf}'' - (Instrument Definition File) beschrieben. Dies sind normale XML Text - Dateien, die für jedes angeschlossene Gerät individuell erstellt werden - können. In einer {\tt *.idf} Datei kann in einem ''Init'' Eintrag eine - Serien von Midi Events definiert werden, die immer dann gesendet werden, - wenn in \M\ der {\tt Midi->InitInstr} Button aktiviert wird. Wir nutzen diese - Möglichkeit, um den S90 zu initialisieren. - - \subsubsection{Local Off} - Wird ein Synthesizer ''standalone'' betrieben, dann ist die Tastatur - intern direkt mit dem Tongenerator verbunden. Am Computer angeschlossen - möchten wir jedoch Tastatur und Tongenerator als unabhängige Teile - benutzen. Note On/Off Events sollen von der Tastatur nur zum Computer - geschickt werden und nicht auch gleich zum internen Tongenerator. - Der Tongenerator soll wiederum nur auf den Midi Input Anschluß hören - und nicht auf die Tastatur. Für den S90 kann dieser ''Local Off'' - Mode durch Senden des SysEx Strings - - \starttyping - 0xf0 0x10 0x6b 0x00 0x00 0x09 0x00 - \stoptyping - - eingeschaltet werden. - - \subsubsection{Sequencer Mode} - Der S90 kenn Yamaha-Typisch verschiedene Modi. Wir benutzen den - Sequencer Mode, in dem jedem Midi Kanal ein eigenes Instrument - zugeordnet werden kann. Dieser Modus wird mit dem SysEx String - - \starttyping - 0xf0 0x43 0x10 0x6b 0x0a 0x00 0x00 0x00 - \stoptyping - - eingeschaltet. Beide SysEx Kommandos sind unter dem ''init'' Label in - der {\tt Yamaha-S90.idf} Datei eingetragen. - - \subsubsection{Midi Input Filter} - Die Tastatur des Yamaha S90 kann ''After Touch'' Events erzeugen, d.h. - nach dem Drücken einer Taste werden fortlaufend Events über den - Anpreßdruck der Taste erzeugt. Diese Informationen benötigen wir - nicht und filtern deshalb alle After Touch Events gleich bei der - Aufnahme mittels des Midi Input Filters aus. - - \Fig{midifilter} - - \subsection{Aufnehmen} diff --git a/muse/doc/man/de/miditracks.tex b/muse/doc/man/de/miditracks.tex deleted file mode 100644 index 6e3a06c2..00000000 --- a/muse/doc/man/de/miditracks.tex +++ /dev/null @@ -1,132 +0,0 @@ - \section{Midi Routing} - - \section{Midi Setup} - \subsection{Einfaches Setup} - - In einem einfachen Setup ist jeder Midi Anschluss des Rechners - jeweils mit nur einem Midi Gerät verbunden. Außerdem hat jede - Midi Spur einen eigenen Midi Kanal. - Dieses Setup ist am flexibelsten und sollte nach Möglichkeit - immer verwendet werden. - - \subsection{Erweitertes Setup} - - \index{mehrere Midi Spuren für einen Midi Kanal} - Im erweiterten Setup werden mehrere Midi Spuren auf den gleichen - Midi Kanal geroutet. Es ist zu beachten, das Midi Controller - natürlich immer für alle Spuren des Kanals gelten. Controller - können nicht individuell für jede Spur eingestellt werden. - - \subsection{Komplexes Setup} - \index{mehrere Geräte an einem Midi Anschluß} - Als komplex bezeichnen wir ein Setup, in dem an einem Midi Anschluß - mehrere Midi Geräte angeschlossen sind. - Jedes Gerät belegt einen oder mehrere der verfügbaren 16 Midi - Kanäle. Es ist darauf zu achten, das die vergebenen Kanäle nicht - überlappen. Dazu müssen die angeschlossenen Midi Geräte so - konfiguriert werden, das sie nur auf die ihnen zugewiesenen Kanäle - reagieren. - - Midi Meldungen, die nicht kanalgebunden sind (wie z.B. Sysex - Meldungen) können an bestimmte Geräte gesendet werden, indem - man jedem Gerät eine individuelle Geräte-Id gibt. Diese Geräte-Id - muß dann in die entsprechenden Meldungen als Zieladresse angegeben - werden. - - Da Midi Verbindungen nur eine sehr bescheidene \index{Midi Bandbreite} - Bandbreite besitzen, sollte nach Möglichkeit das komplexe Setup - vermieden werden. - - \section{Midi Eingänge} - Ein Midi Eingang wird im Mixer als Strip und im Arranger als - eigene Spur gezeigt. - - Ein Midi Eingang hat folgende Eigenschaften: - - \blank[big] - \Input{Alsa Port:} dies ist die Route zu einem ALSA Midi Eingangs - Port. Ein ALSA Port kann mit mehreren Midi Eingängen verbunden - werden. - \Input{Plugins:} die von ALSA gelesenen Midi Events können durch - mehrere Plugins geroutet werden. Verfügbare Plugins filtern oder - verändern die Midi Events. - \Input{Outputs:} ein Midi Eingang hat 16 Ausgänge, jeweils ein - Ausgang für jeden Midi Kanal. Jeder Midi Kanal kann individuell - zu einem oder mehreren Midi Spuren geroutet werden. - Midi Events, die von den Midi Spuren empfangen werden, haben - keine Kanal-Information mehr. - In einem einfachen Setup werden alle Kanäle aller Midi Eingänge - zu allen Midi Spuren geroutet. Dies ist die Standard Vorgabe. - \par - - \blank[big] - - \section{Midi Spur} - Die Midi Spur enthält alle Midi Note On/off Events. Sie wird im - Mixer als Strip und im Arranger als Spur dargestellt. Die - Strip Darstellung im Mixer ist nicht sehr interessant, da eine - Midi Spur kaum eigene Mixer relevante Parameter besitzt. In einem - normalen Setup sollten Midi Spuren im Mixer ausgeblendet werden. - - Midi Spur Eigenschaften: - - \blank[big] - \Input{Record:} schaltet die Spur in den Record Modus - - \Input{Monitor:} ist der Monitor Schalter eingeschaltet, werden - bei Record alle Input Events zum Ausgang weitergereicht. - Achtung: dies kann möglicherweise zu Midi Rückkopplungen - führen! - - \Input{Mute:} schaltet die Spur stumm - - \Input{Solo:} ---nocht nicht definiert--- - - \Input{Eingang:} die Spur Eingänge können zu Midi Eingängen - geroutet werden - - \Input{Ausgang:} der Spur Ausgang kann zu einem oder mehreren - Midi Kanälen geroutet werden. Midi Kanäle sind immer mit - einem Midi Port verbunden. - - \blank[big] - - \section{Midi Kanäle} - Midi Kanäle enthalten normalerweise alle Midi Controller Events. - - Midi Kanal Eigenschaften: - - \blank[big] - - \blank[big] - - \section{Midi Port} - - \index{Midi Port} Ein Midi Port representiert ein externes Midi - Gerät und hat folgende Eigenschaften: - - \blank[big] - \Input{Instrument:} \index{Midi Instrument} beschreibt die - Eigenschaften des externen - Midi Instruments. Das Instrument kann aus einer Liste verfügbarer - Instrumentbeschreibungen ausgewählt werden. - - \Input{Master Volume:} \index{Midi Master Volume} ist ein Midi - Controller, der die Lautstärke für alle Channel des Midi Ports - einstellt. - - \Input{Geräte Id:} \index{Midi Geräte Id} werden mehrere Midigeräte - an einen Midi Port - angeschlossen, so müssen alle Geräte eine eindeutige Geräte Id - besitzen. Mit dieser Id kann dann ein bestimmtes Gerät - ausgewählt werden. - - \Input{Alsa Port:} dies ist die Route zu einem ALSA Midi Port. - Ein Port Ausgang kann mit mehreren ALSA Ports verbunden werden. - - \blank[big] - - Jeder Midi Port besitzt 16 Kanäle. - - \section{Midi Synthesizer} - diff --git a/muse/doc/man/de/projekte.tex b/muse/doc/man/de/projekte.tex deleted file mode 100644 index dcaa6c9a..00000000 --- a/muse/doc/man/de/projekte.tex +++ /dev/null @@ -1,102 +0,0 @@ -\chapter{Projekte} - - \section{Projekte} - - Ein \M\ Projekt \index{Projekt} ist ein Ordner, der alle - Dateien des Projekts enthält. Dies sind im wesentlichen die - aufgenommenen Wavedateien und die Projektdatei \index{Projektdatei}. - Die Projektdatei enthält alle - Informationen über das Projekt sowie alle Midi Daten soweit - vorhanden. - - Beispiel einer Projekt Ordnerstruktur: - - \starttyping - ~/MusE - projects - song1 - song1.med - rec1.wav - rec1.wca - rec2.wav - rec2.wca - song2 - . - . - \stoptyping - - Im oberen Beispiel ist {\tt song1} der Projektordner - \index{Projektordner} und - {\tt song1.med} die Projektdatei. Die {\tt *.wav} Dateien sind - Audio Aufzeichnungen und die zugehörigen {\tt *.wca} Dateien - enthalten vorberechnete Daten zum schnellen Zeichnen der - Wellenformdarstellung auf den Bildschirm. - - Der Standard-Projektordner \index{Standard-Projektordners} - {\tt ~/MusE/projects} kann im ''Präferenzen'' Menü eingestellt - werden. - - \section{Projekt auswählen} - - Nach dem Start von \M\ muß immer zunächst ein Projekt geladen oder - ein neues Projekt erzeugt werden. - - \Screen{select_project}{Projekt auswählen} - - Normalerweise wird nach dem Start von \M\ das zuletzt bearbeitete - Projekt geladen. Wer das nicht mag kann unter ''Präferenzen'' - einstellen, ob beim Start ein Standardprojekt \index{Standardprojekt} - geladen oder immer zunächst nach einen Projekt gefragt werden soll. - - \section{Templates} - - Wird bei der Projektauswahl ein neues Projekt ausgewählt, dann - wird im nächsten Schritt ein Dialog gezeigt, in dem ein Template - aus einer Liste von verfügbaren Templates ausgewählt werden kann. - Ein Template bestimmt die Grundeinstellungen für ein neues - Projekt. Ein Template kann ein komplettes Projekt sein, welches - jedoch keine Audiodaten enthalten kann und welches in der Regel - auch keine Midi Daten enthält. - - \Screen{select_template}{Template auswählen} - - \M\ sucht Templates an zwei Orten: - im globalen \M\ Installationspfad (Factory Presets) sowie im - \M\ Verzeichnis relativ zum {\tt HOME} Verzeichnis des - Anwenders (User Presets) - - \section{Projekt sichern (Backup)} - - Es gibt keine in \M\ eingebaute Funktion zum Sichern von Projekten. - Da sich aber alle Projektdaten in einem Ordner befinden, - können Standard-Tools zum Sichern verwendet werden. - - Projekte sind immer in sich komplett und enthalten keine Verweise - auf Dateien außerhalb des Projektordners. Dies gilt nicht - für Soundfonts \index{Soundfonts}, die z.B. vom Fluid-Synthesizer - Plugin verwendet werden. - Es wird empfohlen, diese Soundfonts\index{Soundfonts} - auch als Kopie im Projektordner abzulegen. - - Projekte können auf der Platte ohne Probleme verschoben werden, - da sie keine absoluten Pfade enthalten. - - \section{Wavedateien und Samplerate} - - \index{Wavedateien}\index{Audioprojekte}\index{Midiprojekte} - \index{Samplerate} - MusE unterscheidet zwischen Midiprojekten und Audioprojekten. - Audioprojekte enthalten zusätzlich zu eventuell vorhandenen - Mididaten Wavedateien. - - Audioprojekte sind immer mit einer bestimmten Samplerate - verbunden und können nur geladen und bearbeitet werden, wenn - die Projekt Samplerate mit der aktuellen Samplerate übereinstimmt. - - Die aktuelle Samplerate wird immer vom JACK Server bestimmt und - kann von \M\ nicht verändert werden. - - Werden Wavedateien mit einer anderen Samplerate als der aktuellen - importiert, so müssen sie konvertiert (resampled\index{resample}) - werden. - diff --git a/muse/doc/man/de/struktur.tex b/muse/doc/man/de/struktur.tex deleted file mode 100644 index bd762d79..00000000 --- a/muse/doc/man/de/struktur.tex +++ /dev/null @@ -1,43 +0,0 @@ -\chapter{Struktur} - \section{Spuren} - - Ein Projekt besteht aus Spuren analog einer analogen Bandmaschine. - Die Spuren enthalten Midi- Audio- oder Controllerdaten. - Spuren werden in \M\ in zwei Formen dargestellt: - - \blank[big] - \Input{Arranger:} im Arranger werden alle Spuren vertikal in einer - Liste dargestellt - - \Input{Mixer:} der Mixer zeigt alle Spuren in einer horizontalen - Darstellung\par - - \blank[big] - - Tempo und Taktart sind interne Spuren, die nicht im Arranger oder - Mixer gezeigt werden. - - \section{Parts} - - Midi- und Audiospuren können auf der Zeitachse in Parts unterteilt - werden. Parts enthalten Midi- Audio- oder Conrollerdaten. - - Folgenden Operationen sind mit Parts möglich: - - \blank[big] - \Input{verschieben} Parts können auf der Zeitachse und in andere - Spuren des gleichen Typs verschoben werden. - \Input{kopieren} klar! - \Input{klonen} erzeugt einen Part, der sich die Midi- Audio- oder - Controllerdaten mit dem Quellpart teilt. Wird ein Event in - einem Clone-Parts verändert, so verändern sich auch alle - Clones. - - \Input{Stumm} Parts können stumm geschaltet werden. Stumme Parts - werden im Arranger grau dargestellt. - - \par - \blank[big] - - - diff --git a/muse/doc/manual-de.odt b/muse/doc/manual-de.odt new file mode 100644 index 00000000..1a8fb669 Binary files /dev/null and b/muse/doc/manual-de.odt differ diff --git a/muse/muse/CMakeLists.txt b/muse/muse/CMakeLists.txt index 000a8787..9ef460c3 100644 --- a/muse/muse/CMakeLists.txt +++ b/muse/muse/CMakeLists.txt @@ -32,7 +32,6 @@ subdirs ( instruments marker liste - arranger waveedit ) @@ -48,6 +47,9 @@ QT4_WRAP_UI (muse_ui_headers templatedialog.ui importmidi.ui routedialog.ui + configtrack.ui + midiportinfo.ui + miditrackinfo.ui ) QT4_WRAP_CPP ( muse_moc_headers @@ -85,6 +87,15 @@ QT4_WRAP_CPP ( muse_moc_headers rack.h routedialog.h strip.h + arranger.h + canvas.h + configtrack.h + partdrag.h + tllineedit.h + tlswidget.h + tlwidget.h + trackdrag.h + trackinfo.h ) QT4_ADD_RESOURCES (muse_qrc_files muse.qrc) @@ -173,6 +184,17 @@ add_executable ( muse rack.cpp routedialog.cpp strip.cpp + + arranger.cpp + canvas.cpp + configtrack.cpp + partdrag.cpp + tllineedit.cpp + tlswidget.cpp + tlwidget.cpp + tlwlayout.cpp + trackdrag.cpp + trackinfo.cpp ) set_target_properties( muse @@ -186,7 +208,6 @@ target_link_libraries(muse marker liste synti - arranger waveedit widgets al diff --git a/muse/muse/arranger.cpp b/muse/muse/arranger.cpp new file mode 100644 index 00000000..82c859cb --- /dev/null +++ b/muse/muse/arranger.cpp @@ -0,0 +1,1382 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "song.h" +#include "muse.h" +#include "arranger.h" +#include "tlwidget.h" +#include "tlswidget.h" +#include "icons.h" +#include "widgets/simplebutton.h" +#include "configtrack.h" +#include "canvas.h" +#include "widgets/utils.h" +#include "widgets/splitter.h" +#include "astrip.h" +#include "mstrip.h" +#include "audio.h" +#include "shortcuts.h" +#include "trackinfo.h" +#include "midictrl.h" +#include "gconfig.h" +#include "part.h" + +//--------------------------------------------------------- +// TrElement elements +// list of available track gui elements +//--------------------------------------------------------- + +const TrElement trElements[] = { + TrElement(TR_NAME, 1, "trackname", -1), + TrElement(TR_RECORD, 0, "record", + Track::M_MIDI | Track::M_AUDIO_OUTPUT | Track::M_WAVE), + TrElement(TR_OFF, 2, "off", + Track::M_AUDIO_OUTPUT + | Track::M_AUDIO_GROUP + | Track::M_WAVE + | Track::M_AUDIO_INPUT + | Track::M_AUDIO_SOFTSYNTH), + TrElement(TR_DRUMMAP, 2, "use drum map", Track::M_MIDI), + TrElement(TR_MUTE, 3, "mute", -1), + TrElement(TR_SOLO, 3, "solo", -1), + TrElement(TR_MONITOR, 3, "monitor", + Track::M_MIDI | Track::M_WAVE), + TrElement(TR_AREAD, 4, "automation read", + -1 & ~(Track::M_MIDI_IN | Track::M_MIDI)), + TrElement(TR_AWRITE, 4, "automation write", + -1 & ~(Track::M_MIDI_IN | Track::M_MIDI)), + TrElement(TR_OCHANNEL, 5, "output channel", Track::M_MIDI), + TrElement(TR_INSTRUMENT, 6, "instrument", Track::M_MIDI_OUT), + TrElement(TR_PATCH, 7, "patch", Track::M_MIDI), + }; + +const int nTrElements = sizeof(trElements)/sizeof(*trElements); + +TrGroupList glist[Track::TRACK_TYPES]; + +extern void populateAddTrack(QMenu*); + +//--------------------------------------------------------- +// sizeHint +//--------------------------------------------------------- + +QSize InfoStack::sizeHint() const + { + return QSize(infoWidth, height()); + } + +//--------------------------------------------------------- +// TLayout +// simple layout for trackList +//--------------------------------------------------------- + +class TLayout : public QLayout { + QList itemList; + + public: + TLayout() {} + ~TLayout(); + + void addItem(QLayoutItem* item); + void insertWidget(int index, QWidget* item); + Qt::Orientations expandingDirections() const { return 0; } + bool hasHeightForWidth() const { return false; } + int count() const { return itemList.size(); } + void setGeometry(const QRect &rect); + QSize sizeHint() const { return ((QWidget*)parent())->size(); } + QLayoutItem *itemAt(int index) const { return itemList.value(index); } + QLayoutItem *takeAt(int idx) { + return idx >= 0 && idx < itemList.size() ? itemList.takeAt(idx) : 0; + } + void clear() { + QLayoutItem* child; + while ((child = takeAt(0)) != 0) { + delete child; + } + } + }; + +//--------------------------------------------------------- +// TLayout +//--------------------------------------------------------- + +TLayout::~TLayout() + { + QLayoutItem* child; + while ((child = takeAt(0)) != 0) + delete child; + } + +//--------------------------------------------------------- +// insertWidget +//--------------------------------------------------------- + +void TLayout::insertWidget(int index, QWidget* item) + { + if (item->parent() == 0) + item->setParent((QWidget*)parent()); + itemList.insert(index, new QWidgetItem(item)); + update(); + } + +//--------------------------------------------------------- +// addItem +//--------------------------------------------------------- + +void TLayout::addItem(QLayoutItem* item) + { + itemList.append(item); + update(); + } + +//--------------------------------------------------------- +// setGeometry +//--------------------------------------------------------- + +void TLayout::setGeometry(const QRect& r) + { + int y = r.y(); + int n = itemList.size(); + int width = r.width(); // ((QWidget*)parent())->width(); + for (int i = 0; i < n; ++i) { + QLayoutItem *item = itemList.at(i); + QWidget* w = item->widget(); + int h = w->height(); + w->setGeometry(0, y, width, h); + y += h; + } + } + +//--------------------------------------------------------- +// TlsvLayout +//--------------------------------------------------------- + +class TlsvLayout : public QLayout { + QList itemList; + int dx, dy; + + public: + TlsvLayout() { + dx = 0; + dy = 0; + } + ~TlsvLayout(); + + void setOffset(int x, int y) { + dx = x; + dy = y; + } + void addItem(QLayoutItem* item); + void insertWidget(int index, QWidget* item); + Qt::Orientations expandingDirections() const { return 0; } + bool hasHeightForWidth() const { return false; } + int count() const { return itemList.size(); } + void setGeometry(const QRect &rect); + QSize sizeHint() const { return ((QWidget*)parent())->size(); } + QLayoutItem *itemAt(int index) const { return itemList.value(index); } + QLayoutItem *takeAt(int idx) { + return idx >= 0 && idx < itemList.size() ? itemList.takeAt(idx) : 0; + } + }; + +//--------------------------------------------------------- +// TlsvLayout +//--------------------------------------------------------- + +TlsvLayout::~TlsvLayout() + { + QLayoutItem* child; + while ((child = takeAt(0)) != 0) + delete child; + } + +//--------------------------------------------------------- +// insertWidget +//--------------------------------------------------------- + +void TlsvLayout::insertWidget(int index, QWidget* item) + { + if (item->parent() == 0) + item->setParent((QWidget*)parent()); + itemList.insert(index, new QWidgetItem(item)); + update(); + } + +//--------------------------------------------------------- +// addItem +//--------------------------------------------------------- + +void TlsvLayout::addItem(QLayoutItem* item) + { + itemList.append(item); + update(); + } + +//--------------------------------------------------------- +// setGeometry +//--------------------------------------------------------- + +void TlsvLayout::setGeometry(const QRect& r) + { + QLayoutItem *item = itemList.at(0); + QWidget* w = item->widget(); + w->setGeometry(dx, dy, r.width(), w->height()); + } + +//--------------------------------------------------------- +// newAddTrackMenu +//--------------------------------------------------------- + +QMenu* newAddTrackMenu(QWidget* parent) + { + QMenu* menu = new QMenu(parent); + populateAddTrack(menu); + return menu; + } + +//--------------------------------------------------------- +// Arranger +//--------------------------------------------------------- + +Arranger::Arranger(QMainWindow* parent) + : QWidget(parent) + { +// setFocusPolicy(Qt::StrongFocus); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + for (int i = 0; i < Track::TRACK_TYPES; ++i) + trackInfos[i] = 0; + + zeroTrackInfo = 0; + _curTrack = 0; + strip = 0; + info = 0; + tool = PointerTool; + + for (int tt = 0; tt < Track::TRACK_TYPES; ++tt) { + int gn = 0; + TrElementList group; + for (int i = 0; i < nTrElements; ++i) { + if (!(trElements[i].trackMask & (1<setSpacing(0); + ml->setMargin(0); + setLayout(ml); + + infoDock = new QDockWidget(tr("TrackInfo")); + infoDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + infoDockAction = infoDock->toggleViewAction(); + + mixerDock = new QDockWidget(tr("")); + mixerDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + mixerDockAction = mixerDock->toggleViewAction(); + + parent->setDockNestingEnabled(true); + + parent->addDockWidget(Qt::LeftDockWidgetArea, infoDock, Qt::Horizontal); + parent->addDockWidget(Qt::LeftDockWidgetArea, mixerDock, Qt::Horizontal); + + infoView = new QScrollArea; + infoView->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); + + infoDock->setWidget(infoView); + infoView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + trackInfo = new InfoStack(); + infoView->setWidget(trackInfo); + infoView->setWidgetResizable(true); + + trackInfoVisible = false; + mixerStripVisible = false; + + infoDock->setVisible(false); + mixerDock->setVisible(false); + + connect(infoDockAction, SIGNAL(toggled(bool)), SLOT(toggleTrackInfo(bool))); + connect(mixerDockAction, SIGNAL(toggled(bool)), SLOT(toggleMixerStrip(bool))); + + tlsv = new TrackListWidget; + tlsv->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + tlsvLayout = new TlsvLayout; + tlsv->setLayout(tlsvLayout); + trackList = new QWidget; + trackList->setAttribute(Qt::WA_StaticContents); + trackList->setMouseTracking(true); + + tlsv->layout()->addWidget(trackList); + tl = new TLayout; + trackList->setLayout(tl); + + // + // Toolbox + // + QHBoxLayout* ttoolsLayout = new QHBoxLayout; + ttoolsLayout->setMargin(1); + ttoolsLayout->setSpacing(1); + + SimpleButton* configButton = new SimpleButton(configIcon, configIcon); + configButton->setAutoRaise(true); + configButton->setToolTip(tr("Config Tracklist")); + configButton->setFixedHeight(rulerHeight-4); + connect(configButton, SIGNAL(clicked()), SLOT(configTrackList())); + ttoolsLayout->addWidget(configButton); + ttoolsLayout->addStretch(100); + + gmute = newMuteButton(); + gmute->setFixedWidth(rulerHeight); + gmute->setToolTip(tr("all mute off")); + gmute->setFixedHeight(rulerHeight-4); + ttoolsLayout->addWidget(gmute); + setGMute(); + connect(song, SIGNAL(muteChanged(Track*,bool)), SLOT(setGMute())); + connect(gmute, SIGNAL(clicked(bool)), SLOT(offGMute())); + + gsolo = newSoloButton(); + gsolo->setFixedWidth(rulerHeight); + gsolo->setToolTip(tr("all solo off")); + gsolo->setFixedHeight(rulerHeight-4); + ttoolsLayout->addWidget(gsolo); + setGSolo(); + connect(song, SIGNAL(soloChanged(Track*,bool)), SLOT(setGSolo())); + connect(gsolo, SIGNAL(clicked(bool)), SLOT(offGSolo())); + + gar = newAutoReadButton(); + gar->setFixedWidth(rulerHeight); + gar->setToolTip(tr("all autoRead off")); + gar->setFixedHeight(rulerHeight-4); + ttoolsLayout->addWidget(gar); + setGar(); + connect(song, SIGNAL(autoReadChanged(Track*,bool)), SLOT(setGar())); + connect(gar, SIGNAL(clicked(bool)), SLOT(offGar())); + + gaw = newAutoWriteButton(); + gaw->setFixedWidth(rulerHeight); + gaw->setToolTip(tr("all autoWrite off")); + gaw->setFixedHeight(rulerHeight-4); + ttoolsLayout->addWidget(gaw); + setGaw(); + connect(song, SIGNAL(autoWriteChanged(Track*,bool)), SLOT(setGaw())); + connect(gaw, SIGNAL(clicked(bool)), SLOT(offGaw())); + + QHBoxLayout* infoboxLayout = new QHBoxLayout; + infoboxLayout->setMargin(1); + infoboxLayout->setSpacing(1); + + SimpleButton* tifButton = new SimpleButton(QString()); + tifButton->setCheckable(true); + tifButton->setFixedSize(infoHeight-2, infoHeight); + tifButton->setDefaultAction(infoDockAction); + infoDockAction->setText(tr("i")); + infoDockAction->setToolTip(tr("Show Track Info")); + infoboxLayout->addWidget(tifButton); + + SimpleButton* mstButton = new SimpleButton(QString()); + mstButton->setCheckable(true); + mstButton->setFixedSize(infoHeight-2, infoHeight); + mstButton->setDefaultAction(mixerDockAction); + mixerDockAction->setText(tr("m")); + mixerDockAction->setToolTip(tr("Show Mixer Strip")); + infoboxLayout->addWidget(mstButton); + + infoboxLayout->addStretch(100); + + split = new Splitter(Qt::Horizontal); + split->setOpaqueResize(true); + split->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + QWidget* tw = new QWidget; + split->addWidget(tw); + QVBoxLayout* trackListGrid = new QVBoxLayout; + trackListGrid->setMargin(0); + trackListGrid->setSpacing(0); + tw->setLayout(trackListGrid); + + trackListGrid->addLayout(ttoolsLayout); + QFrame* ruler = hLine(0); + ruler->setLineWidth(2); + trackListGrid->addWidget(ruler); + trackListGrid->addWidget(tlsv, 100); + trackListGrid->addLayout(infoboxLayout); + + // + // canvas widget + // + canvas = new PartCanvas; + canvas->setCornerWidget(new QSizeGrip(canvas)); + split->addWidget(canvas); + split->setStretchFactor(1, 100); + canvas->setTool(tool); + canvas->verticalScrollBar()->setSingleStep(minTrackHeight/2); + + connect(tlsv, SIGNAL(mouseWheel(QWheelEvent*)), SLOT(mouseWheel(QWheelEvent*))); + connect(song, SIGNAL(posChanged(int,const AL::Pos&,bool)), canvas, SLOT(setLocatorPos(int,const AL::Pos&,bool))); + connect(song, SIGNAL(lenChanged(const AL::Pos&)), canvas, SLOT(setEndPos(const AL::Pos&))); + connect(song, SIGNAL(tempoChanged()), canvas, SLOT(tempoChanged())); + connect(canvas, SIGNAL(kbdMovementUpdate(Track*, Part*)), SLOT(kbdMovementUpdate(Track*, Part*))); + connect(muse, SIGNAL(rasterChanged(int)), canvas, SLOT(setRaster(int))); + connect(canvas, SIGNAL(cursorPos(const AL::Pos&,bool)), SIGNAL(cursorPos(const AL::Pos&,bool))); + connect(canvas, SIGNAL(contentsMoving(int,int)), SLOT(setTLViewPos(int,int))); + connect(canvas, SIGNAL(posChanged(int,const AL::Pos&)), SLOT(setPos(int,const AL::Pos&))); + + connect(canvas, SIGNAL(createLRPart(Track*)), song, SLOT(cmdCreateLRPart(Track*))); + connect(canvas, SIGNAL(doubleClickPart(Part*)), SIGNAL(editPart(Part*))); + connect(canvas, SIGNAL(startEditor(Part*,int)), muse, SLOT(startEditor(Part*,int))); + connect(canvas, SIGNAL(partChanged(Part*,unsigned,unsigned)), + song, SLOT(cmdChangePart(Part*,unsigned,unsigned))); + connect(canvas, SIGNAL(addMarker(const AL::Pos&)), SLOT(addMarker(const AL::Pos&))); + connect(canvas, SIGNAL(removeMarker(const AL::Pos&)), SLOT(removeMarker(const AL::Pos&))); + + layout()->addWidget(split); + + connect(muse, SIGNAL(configChanged()), SLOT(updateConfiguration())); + connect(song, SIGNAL(trackSelectionChanged(Track*)), SLOT(setSelectedTrack(Track*))); + connect(song, SIGNAL(trackRemoved(Track*)), SLOT(removeTrack(Track*))); + connect(song, SIGNAL(trackAdded(Track*,int)), SLOT(insertTrack(Track*))); + connect(muse, SIGNAL(startLoadSong()), SLOT(startLoadSong())); + } + +//--------------------------------------------------------- +// setPos +//--------------------------------------------------------- + +void Arranger::setPos(int idx, const AL::Pos& pos) + { + song->setPos(idx, pos.snaped(muse->raster())); + } + +//--------------------------------------------------------- +// setTLViewPos +//--------------------------------------------------------- + +void Arranger::setTLViewPos(int /*x*/, int y) + { +#if 1 + int dy = y + trackList->y(); + tlsv->scroll(0, -dy); +#else + trackList->setGeometry(0, -y, trackList->width(), trackList->height()); +#endif + tlsvLayout->setOffset(0, -y); + } + +//--------------------------------------------------------- +// tlIndex +//--------------------------------------------------------- + +int Arranger::tlIndex(Track* t) const + { + const TrackList* stl = song->tracks(); + + int idx = 0; + for (ciTrack i = stl->begin(); i != stl->end(); ++i, ++idx) { + if (*i == t) + break; + ArrangerTrack* at = &(*i)->arrangerTrack; + if (at->tw == 0) + continue; + idx += (*i)->subtracks.size(); + } + return idx; + } + +int Arranger::tlIndex(ArrangerTrack* t) const + { + TrackList* stl = song->tracks(); + + int idx = 0; + for (ciTrack i = stl->begin(); i != stl->end(); ++i, ++idx) { + ArrangerTrack* at = &(*i)->arrangerTrack; + if (at->tw == 0) + continue; + ArrangerTrackList& atl = (*i)->subtracks; + for (iArrangerTrack k = atl.begin(); k != atl.end(); ++k) { + ++idx; + if (*k == t) + return idx; + } + } + return -1; // crash + } + +//--------------------------------------------------------- +// insertTrack +//--------------------------------------------------------- + +void Arranger::insertTrack1(Track* t) + { + int idx = tlIndex(t); + //------------------------- + // track list widget + //------------------------- + + TLWidget* tw = new TLWidget(t, &glist[t->type()]); + tw->setFixedHeight(t->arrangerTrack.h); + tl->insertWidget(idx, tw); + tw->show(); // needed if song is reloaded + + connect(tw, SIGNAL(plusClicked(TLWidget*)), SLOT(appendSubtrack(TLWidget*))); + connect(tw, SIGNAL(moveTrack(Track*,Track*)), SLOT(moveTrack(Track*,Track*))); + connect(this, SIGNAL(configChanged()), tw, SLOT(configChanged())); + connect(tw, SIGNAL(drag(int, int)), SLOT(drag(int,int))); + connect(tw, SIGNAL(startDrag(int)), SLOT(startDrag(int))); + connect(t, SIGNAL(partsChanged()), canvas->widget(), SLOT(update())); + + ArrangerTrack* at = &(t->arrangerTrack); + at->tw = tw; + } + +void Arranger::insertTrack(Track* t) + { + insertTrack1(t); + t->arrangerTrack.tw->show(); + updateIndex(); + if (_curTrack == 0) + setSelectedTrack(_curTrack); + } + +//--------------------------------------------------------- +// removeTrack +//--------------------------------------------------------- + +void Arranger::removeTrack(Track* t) + { + ArrangerTrack* at = &t->arrangerTrack; + if (at->tw == 0) + return; + + tl->removeWidget(at->tw); + + at->tw->close(); + at->tw = 0; + + for (iArrangerTrack i = t->subtracks.begin(); i != t->subtracks.end(); ++i) { + ArrangerTrack* at = *i; + tl->removeWidget(at->tw); + at->tw->close(); + } + t->subtracks.clear(); + + if (t == _curTrack) { + if (!song->tracks()->isEmpty()) + song->selectTrack(song->tracks()->front()); + } + updateIndex(); + } + +//--------------------------------------------------------- +// drag +//--------------------------------------------------------- + +void Arranger::drag(int trackIdx, int delta) + { + int h = startH + delta; + if (h < minTrackHeight) + h = minTrackHeight; + ArrangerTrack* at = atrack(trackIdx); + at->tw->setFixedHeight(h); + updateIndex(); + } + +//--------------------------------------------------------- +// startDrag +//--------------------------------------------------------- + +void Arranger::startDrag(int trackIdx) + { + ArrangerTrack* at = atrack(trackIdx); + startH = at->tw->height(); + } + +//--------------------------------------------------------- +// TrackListWidget +//--------------------------------------------------------- + +TrackListWidget::TrackListWidget(QWidget* parent) + : QWidget(parent) + { + setAttribute(Qt::WA_NoSystemBackground); + setAttribute(Qt::WA_StaticContents); + } + +//--------------------------------------------------------- +// paintEvent +//--------------------------------------------------------- + +void TrackListWidget::paintEvent(QPaintEvent* ev) + { + QPainter p(this); + p.eraseRect(ev->rect()); + } + +//--------------------------------------------------------- +// mousePressEvent +//--------------------------------------------------------- + +void TrackListWidget::mousePressEvent(QMouseEvent* ev) + { + if (ev->button() == Qt::RightButton) { + QMenu* menu = newAddTrackMenu(this); + menu->exec(ev->globalPos()); + } + } + +//--------------------------------------------------------- +// wheelEvent +//--------------------------------------------------------- + +void TrackListWidget::wheelEvent(QWheelEvent* e) + { + emit mouseWheel(e); + } + +//--------------------------------------------------------- +// mouseWheel +// get redirected mouse wheel events from TrackListWidget +//--------------------------------------------------------- + +void Arranger::mouseWheel(QWheelEvent* e) + { + if (e->orientation() != Qt::Vertical) + return; + QScrollBar* sb = canvas->verticalScrollBar(); + int step = qMin(QApplication::wheelScrollLines() * sb->singleStep(), sb->pageStep()); + if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier)) + step = sb->pageStep(); + int offset = e->delta() * step / 120; + if (sb->invertedControls()) + offset = -offset; + if (qAbs(offset) < 1) + return; + sb->setValue(sb->value() + offset); + e->accept(); + } + +//--------------------------------------------------------- +// appendSubtrack +// the user requests a new controller subtrack +//--------------------------------------------------------- + +void Arranger::appendSubtrack(TLWidget* trackWidget) + { + Track* t = trackWidget->track(); + + ArrangerTrack* at = new ArrangerTrack; + at->h = minTrackHeight; + at->ctrl = CTRL_NO_CTRL; + t->subtracks.push_back(at); + if(initSubtrack(t, at)==true) { + updateIndex(); + } + else { + t->subtracks.remove(at); + delete at; + } + } + +//--------------------------------------------------------- +// initSubtrack +//--------------------------------------------------------- + +bool Arranger::initSubtrack(Track* t, ArrangerTrack* at) + { + TLSWidget* tw = new TLSWidget(t, at, canvas); + tw->setFixedHeight(at->h); + + if(tw->setCtrl(at->ctrl) == true) { + tl->insertWidget(tlIndex(at), tw); + at->tw = tw; + connect(tw, SIGNAL(minusClicked(TLSWidget*)), SLOT(removeSubtrack(TLSWidget*))); + connect(tw, SIGNAL(controllerChanged(int)), canvas->widget(), SLOT(update())); + connect(tw, SIGNAL(drag(int, int)), SLOT(drag(int,int))); + connect(tw, SIGNAL(startDrag(int)), SLOT(startDrag(int))); + tw->show(); + } + else { + delete tw; + return false; + } + return true; + } + +//--------------------------------------------------------- +// removeSubtrack +//--------------------------------------------------------- + +void Arranger::removeSubtrack(TLSWidget* w) + { + Track* t = w->track(); + for (iArrangerTrack it = t->subtracks.begin(); it != t->subtracks.end(); ++it) { + ArrangerTrack* at = *it; + if (at->tw == w) { + tl->removeWidget(at->tw); +// at->tw->close(); + delete at->tw; + t->subtracks.erase(it); + delete at; + break; + } + } + updateIndex(); + } + +//--------------------------------------------------------- +// configTrackList +//--------------------------------------------------------- + +void Arranger::configTrackList() + { + if (configTrackEditor == 0) { + configTrackEditor = new ConfigTrackList(this); + connect(configTrackEditor, SIGNAL(trackConfigChanged()), SIGNAL(configChanged())); + } + configTrackEditor->show(); + } + +//--------------------------------------------------------- +// atrack +//--------------------------------------------------------- + +ArrangerTrack* Arranger::atrack(int idx) + { + int k = 0; + TrackList* stl = song->tracks(); + for (iTrack i = stl->begin(); i != stl->end(); ++i) { + ArrangerTrack* at = &(*i)->arrangerTrack; + if (idx == k) + return at; + ++k; + for (iArrangerTrack it = (*i)->subtracks.begin(); it != (*i)->subtracks.end(); ++it) { + ArrangerTrack* t = *it; + if (idx == k) + return t; + ++k; + } + } + return 0; + } + +//--------------------------------------------------------- +// updateIndex +// update vertical scrollbar & index values +//--------------------------------------------------------- + +void Arranger::updateIndex() + { + int idx = 0; + int h = 2 * defaultTrackHeight; // always show room for at least two + // tracks at end of list + + TrackList* stl = song->tracks(); + for (iTrack i = stl->begin(); i != stl->end(); ++i) { + ArrangerTrack* at = &(*i)->arrangerTrack; + if (at->tw == 0) + continue; + ((TLWidget*)at->tw)->setIdx(idx); + h += at->tw->height(); + ++idx; + for (iArrangerTrack it = (*i)->subtracks.begin(); it != (*i)->subtracks.end(); ++it) { + ArrangerTrack* t = *it; + if (t->tw == 0) + continue; + ((TLSWidget*)t->tw)->setIdx(idx); + h += t->tw->height(); + ++idx; + } + } + setGMute(); + setGSolo(); + setGar(); + setGaw(); + canvas->setVSize(h); + trackList->setFixedHeight(h + 32); + canvas->widget()->update(); + QPoint p(canvas->getWPos()); + setTLViewPos(0, p.y()); + } + +//--------------------------------------------------------- +// toggleTrackInfo +//--------------------------------------------------------- + +void Arranger::toggleTrackInfo(bool val) + { + trackInfoVisible = val; + if (trackInfoVisible) { + if (_curTrack == 0) { + if (zeroTrackInfo == 0) { + zeroTrackInfo = new QWidget(this); + trackInfo->addWidget(zeroTrackInfo); + } + trackInfo->setCurrentWidget(zeroTrackInfo); + + return; + } + Track::TrackType t = _curTrack->type(); + TrackInfo* w = trackInfos[t]; + if (w == 0) { + w = trackInfos[t] = createTrackInfo(); + trackInfo->addWidget(w); + } + w->init(_curTrack); + trackInfo->setCurrentWidget(w); + } +// infoDock->layout()->invalidate(); +// infoDock->layout()->update(); + } + +//--------------------------------------------------------- +// toggleMixerStrip +//--------------------------------------------------------- + +void Arranger::toggleMixerStrip(bool val) + { + mixerStripVisible = val; + if (mixerStripVisible && _curTrack) { + if (strip && _curTrack != strip->getTrack()) { + strip->close(); + strip = 0; + } + if (!strip) { + switch(_curTrack->type()) { + case Track::MIDI_IN: + strip = new MidiInPortStrip(0, (MidiInPort*)_curTrack, false); + break; + case Track::MIDI_OUT: + strip = new MidiOutPortStrip(0, (MidiOutPort*)_curTrack, false); + break; + case Track::MIDI_SYNTI: + strip = new MidiSyntiStrip(0, (MidiSynti*)_curTrack, false); + break; + case Track::MIDI: + strip = new MidiStrip(0, (MidiTrack*)_curTrack, false); + break; + default: + strip = new AudioStrip(0, (AudioTrack*)_curTrack, false); + break; + } + // + // it looks like the dock widget has a minimum + // width + strip->setFixedWidth(STRIP_WIDTH + 10); + mixerDock->setWidget(strip); + } + } + else { + if (strip) { + strip->close(); + strip = 0; + } + } + } + +//--------------------------------------------------------- +// startLoadSong +//--------------------------------------------------------- + +void Arranger::startLoadSong() + { + if (strip) + strip->close(); + strip = 0; + + TrackList* stl = song->tracks(); + for (iTrack i = stl->begin(); i != stl->end(); ++i) { + ArrangerTrack* at = &(*i)->arrangerTrack; + tl->removeWidget(at->tw); + at->tw->close(); + delete at->tw; + at->tw = 0; + for (iArrangerTrack it = (*i)->subtracks.begin(); it != (*i)->subtracks.end(); ++it) { + ArrangerTrack* at = *it; + tl->removeWidget(at->tw); + at->tw->close(); + delete at->tw; + } + (*i)->subtracks.clear(); + } + _curTrack = 0; + } + +//--------------------------------------------------------- +// endLoadSong +// create track list widgets +//--------------------------------------------------------- + +void Arranger::endLoadSong() + { + TrackList* stl = song->tracks(); + + for (iTrack i = stl->begin(); i != stl->end(); ++i) { + Track* t = *i; + insertTrack1(t); + for (iArrangerTrack i = t->subtracks.begin(); i != t->subtracks.end(); ++i) { + initSubtrack(t, *i); + } + } + updateIndex(); + setSelectedTrack(song->selectedTrack()); + infoDock->setVisible(trackInfoVisible); + mixerDock->setVisible(mixerStripVisible); + } + +//--------------------------------------------------------- +// updateConfiguration +//--------------------------------------------------------- + +void Arranger::updateConfiguration() + { + if (config.canvasUseBgPixmap) { + canvas->setCanvasBackground(QPixmap(config.canvasBgPixmap)); + } + else + canvas->setCanvasBackground(config.canvasBgColor); +//TD canvas->setShowGrid(config.canvasShowGrid); +//TD update(); + } + +//--------------------------------------------------------- +// readStatus +//--------------------------------------------------------- + +void Arranger::readStatus(QDomNode node) + { + TrackList* tl = song->tracks(); + iTrack it = tl->begin(); + + QPoint wpos; + double xmag = 0.05; + double ymag = 1.0; + + for (; !node.isNull(); node = node.nextSibling()) { + QDomElement e = node.toElement(); + QString tag(e.tagName()); + QString s = e.text(); + int i = s.toInt(); + if (tag == "info") + trackInfoVisible = i; + else if (tag == "strip") + mixerStripVisible = i; + else if (tag == "TrackConf") { + } + else if (tag == "hmag") + xmag = s.toDouble(); + else if (tag == "vmag") + ymag = s.toDouble(); + else if (tag == "hpos") + wpos.setX(i); + else if (tag == "vpos") + wpos.setY(i); + else if (tag == "raster") { + muse->initRaster(i); + canvas->setRaster(i); + } + else if (tag == "splitter") { + split->readStatus(node); + QList sizes = split->sizes(); + split->setSizes(sizes); + } + else + printf("Arranger: unknown tag %s\n", tag.toLatin1().data()); + } + canvas->setMag(xmag, ymag); + canvas->setWPos(wpos); + } + +//--------------------------------------------------------- +// writeStatus +//--------------------------------------------------------- + +void Arranger::writeStatus(Xml& xml) + { + xml.stag("arranger"); + + for (int i = 0; i < Track::TRACK_TYPES; ++i) { + TrGroupList* gl = &glist[i]; + xml.stag(QString("TrackConf type=\"%1\"").arg(i)); + for (iTrGroup ig = gl->begin(); ig != gl->end(); ++ig) { + TrElementList& el = *ig; + xml.stag("group"); + for (iTrElement ie = el.begin(); ie != el.end(); ++ie) + xml.tagE(QString("element id=\"%1\"").arg((*ie)->id)); + xml.etag("group"); + } + xml.etag("TrackConf"); + } + xml.tag("info", trackInfoVisible); + xml.tag("strip", mixerStripVisible); + xml.tag("hmag", canvas->xmag()); + xml.tag("vmag", canvas->ymag()); + xml.tag("hpos", canvas->getWPos().x()); + xml.tag("vpos", canvas->getWPos().y()); + xml.tag("raster", muse->raster()); + split->writeStatus("splitter", xml); + xml.etag("arranger"); + } + +//--------------------------------------------------------- +// setGMute +//--------------------------------------------------------- + +void Arranger::setGMute() + { + TrackList* tl = song->tracks(); + bool mute = false; + for (iTrack i = tl->begin(); i != tl->end(); ++i) { + if ((*i)->mute()) { + mute = true; + break; + } + } + gmute->setChecked(mute); + } + +//--------------------------------------------------------- +// setGSolo +//--------------------------------------------------------- + +void Arranger::setGSolo() + { + TrackList* tl = song->tracks(); + bool solo = false; + for (iTrack i = tl->begin(); i != tl->end(); ++i) { + if ((*i)->solo()) { + solo = true; + break; + } + } + gsolo->setChecked(solo); + } + +//--------------------------------------------------------- +// setGar +//--------------------------------------------------------- + +void Arranger::setGar() + { + TrackList* tl = song->tracks(); + bool ar = false; + for (iTrack i = tl->begin(); i != tl->end(); ++i) { + if ((*i)->autoRead()) { + ar = true; + break; + } + } + if (ar == false) { + MidiTrackList* cl = song->midis(); + for (iMidiTrack i = cl->begin(); i != cl->end(); ++i) { + if ((*i)->autoRead()) { + ar = true; + break; + } + } + } + gar->setChecked(ar); + } + +//--------------------------------------------------------- +// setGaw +//--------------------------------------------------------- + +void Arranger::setGaw() + { + TrackList*tl = song->tracks(); + bool aw = false; + for (iTrack i = tl->begin(); i != tl->end(); ++i) { + if ((*i)->autoWrite()) + aw = true; + } + if (aw == false) { + MidiTrackList* cl = song->midis(); + for (iMidiTrack i = cl->begin(); i != cl->end(); ++i) { + if ((*i)->autoWrite()) { + aw = true; + break; + } + } + } + gaw->setChecked(aw); + } + +//--------------------------------------------------------- +// offGMute +//--------------------------------------------------------- + +void Arranger::offGMute() + { + TrackList*tl = song->tracks(); + for (iTrack i = tl->begin(); i != tl->end(); ++i) + song->setMute(*i,false); + gmute->setChecked(false); + } + +//--------------------------------------------------------- +// offGSolo +//--------------------------------------------------------- + +void Arranger::offGSolo() + { + TrackList*tl = song->tracks(); + for (iTrack i = tl->begin(); i != tl->end(); ++i) + song->setSolo(*i, false); + gsolo->setChecked(false); + } + +//--------------------------------------------------------- +// offGar +//--------------------------------------------------------- + +void Arranger::offGar() + { + TrackList*tl = song->tracks(); + for (iTrack i = tl->begin(); i != tl->end(); ++i) + song->setAutoRead(*i, false); + MidiTrackList* cl = song->midis(); + for (iMidiTrack i = cl->begin(); i != cl->end(); ++i) + song->setAutoRead(*i, false); + gar->setChecked(false); + } + +//--------------------------------------------------------- +// offGaw +//--------------------------------------------------------- + +void Arranger::offGaw() + { + TrackList*tl = song->tracks(); + for (iTrack i = tl->begin(); i != tl->end(); ++i) + song->setAutoWrite(*i, false); + MidiTrackList* cl = song->midis(); + for (iMidiTrack i = cl->begin(); i != cl->end(); ++i) + song->setAutoWrite(*i, false); + gaw->setChecked(false); + } + +//--------------------------------------------------------- +// setTool +//--------------------------------------------------------- + +void Arranger::setTool(int t) + { + tool = Tool(t); + canvas->setTool(tool); + } + +//--------------------------------------------------------- +// setSelectedTrack +//--------------------------------------------------------- + +void Arranger::setSelectedTrack(Track* t) + { + _curTrack = t; + toggleTrackInfo(trackInfoVisible); + toggleMixerStrip(mixerStripVisible); + } + +//--------------------------------------------------------- +// moveTrack +// move src before dst +//--------------------------------------------------------- + +void Arranger::moveTrack(Track* src, Track* dst) + { + audio->msgMoveTrack(src, dst); + tl->clear(); + TrackList* stl = song->tracks(); + for (iTrack i = stl->begin(); i != stl->end(); ++i) { + tl->addWidget((*i)->arrangerTrack.tw); + for (iArrangerTrack it = (*i)->subtracks.begin(); it != (*i)->subtracks.end(); ++it) + tl->addWidget((*it)->tw); + } + tl->setGeometry(((QWidget*)tl->parent())->geometry()); + updateIndex(); + } + +//--------------------------------------------------------- +//! \fn Arranger::keyPressEvent(QKeyEvent* e) +//! \brief Called when a key is pressed +//! @param e The key event +//--------------------------------------------------------- + +void Arranger::keyPressEvent(QKeyEvent* /*e*/) + { + printf("Arranger::keyPressEvent\n"); +#if 0 //TODOB + int key = e->key(); + bool keypress_handled = false; + + if (e->modifiers() & Qt::ShiftModifier) + key += Qt::SHIFT; + if (e->modifiers() & Qt::AltModifier) + key += Qt::ALT; + if (e->modifiers() & Qt::ControlModifier) + key += Qt::CTRL; + + if (shortcutsKbdMovement.isValid()) { + if (key == shortcuts[SHRT_SEL_LEFT].key || key == shortcuts[SHRT_SEL_LEFT_ADD].key) { + keypress_handled = true; + bool add = (key == shortcuts[SHRT_SEL_LEFT_ADD].key); + PartList* parts = shortcutsKbdMovement.track()->parts(); + Part* nextLeft = 0; + + for (iPart i = parts->begin(); i != parts->end(); i++) { + Part* tmp = i->second; + if (!nextLeft) { + if (tmp->tick() < shortcutsKbdMovement.getLpos()) + nextLeft = tmp; + } + else { + if (tmp->tick() > nextLeft->tick() && tmp->tick() < shortcutsKbdMovement.getLpos() ) + nextLeft = tmp; + } + } + if (nextLeft) { + song->selectPart(nextLeft, add); + shortcutsKbdMovement.setPart(nextLeft); + shortcutsKbdMovement.setPos(nextLeft->tick(), nextLeft->tick() + nextLeft->lenTick()); + } + } + else if (key == shortcuts[SHRT_SEL_RIGHT].key || key == shortcuts[SHRT_SEL_RIGHT_ADD].key) { + keypress_handled = true; + bool add = (key == shortcuts[SHRT_SEL_RIGHT_ADD].key); + PartList* parts = shortcutsKbdMovement.track()->parts(); + Part* nextRight = 0; + + for (iPart i = parts->begin(); i != parts->end(); i++) { + Part* tmp = i->second; + if (!nextRight) { + if (tmp->tick() > shortcutsKbdMovement.getLpos()) + nextRight = tmp; + } + else { + if (tmp->tick() < nextRight->tick() && tmp->tick() > shortcutsKbdMovement.getLpos() ) + nextRight = tmp; + } + } + if (nextRight) { + song->selectPart(nextRight, add); + shortcutsKbdMovement.setPart(nextRight); + shortcutsKbdMovement.setPos(nextRight->tick(), nextRight->tick() + nextRight->lenTick()); + } + } + + else if (key == shortcuts[SHRT_SEL_ABOVE].key) { + // TODO + } + else if (key == shortcuts[SHRT_SEL_BELOW].key) { + // TODO + } + } // -- end movement + else { + if (key == shortcuts[SHRT_TOOL_POINTER].key) { + emit toolChanged(PointerTool); + return; + } + else if (key == shortcuts[SHRT_TOOL_PENCIL].key) { + emit toolChanged(PencilTool); + return; + } + else if (key == shortcuts[SHRT_TOOL_RUBBER].key) { + emit toolChanged(RubberTool); + return; + } + else if (key == shortcuts[SHRT_TOOL_LINEDRAW].key) { + emit toolChanged(DrawTool); + return; + } + } + // If we haven't dealt with the keypress, pass it along + if (!keypress_handled) { + e->ignore(); + } +#endif +// e->ignore(); + } + + +/*! + \fn Arranger::kbdMovementUpdate(Track* t, Part* p) + \brief Slot connected to canvaswidget, called when a part is selected + @param t Track the selected part belongs to (null if no part selected) + @param p The selected Part (null if no part selected) + */ +void Arranger::kbdMovementUpdate(Track*, Part*) + { + printf("kbdMovementUpdate\n"); +// if (t && p ) { +// // If other track selected: +// if (t != shortcutsKbdMovement.track()) { +// TrackList* stl = song->tracks(); +// for (iTrack i = stl->begin(); i != stl->end(); ++i) { +// if (*i == t) { +// // Set focus and select current track +// t->arrangerTrack.tw->setFocus(); +// song->selectTrack(t); +// } +// } +// } +// shortcutsKbdMovement.setTrack(t); +// shortcutsKbdMovement.setPart(p); +// shortcutsKbdMovement.setPos(p->tick(), p->tick() + p->lenTick()); +// } +// else { // Deselected +// shortcutsKbdMovement.reset(); +// } + } + +//--------------------------------------------------------- +// addMarker +//--------------------------------------------------------- + +void Arranger::addMarker(const AL::Pos& pos) + { + song->addMarker(QString(), pos); + canvas->widget()->update(); + } + +//--------------------------------------------------------- +// removeMarker +//--------------------------------------------------------- + +void Arranger::removeMarker(const AL::Pos& pos) + { + AL::MarkerList* ml = song->marker(); + for (AL::iMarker i = ml->begin(); i != ml->end(); ++i) { + AL::iMarker ni = i; + ++ni; + if (i->second <= pos && (ni == ml->end() || ni->second > pos)) { + song->removeMarker(&(i->second)); + canvas->widget()->update(); + return; + } + } + printf("marker not found\n"); + } diff --git a/muse/muse/arranger.h b/muse/muse/arranger.h new file mode 100644 index 00000000..1c9f6e38 --- /dev/null +++ b/muse/muse/arranger.h @@ -0,0 +1,175 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __ARRANGER_H__ +#define __ARRANGER_H__ + +#include "widgets/tools.h" +#include "track.h" + +namespace AL { + class Xml; + class Pos; + }; +using AL::Xml; +class AL::Pos; + +class Track; +class TrackInfo; +class TLWidget; +class TLSWidget; +class PartCanvas; +class Part; +class SimpleButton; +class Strip; +class ArrangerTrack; +class Splitter; +class TlsvLayout; +class TLayout; + +//--------------------------------------------------------- +// InfoStack +//--------------------------------------------------------- + +class InfoStack : public QStackedWidget { + Q_OBJECT; + + virtual QSize sizeHint() const; + + public: + InfoStack() : QStackedWidget() {} + }; + +//--------------------------------------------------------- +// TrackListWidget +//--------------------------------------------------------- + +class TrackListWidget : public QWidget { + Q_OBJECT + + void mousePressEvent(QMouseEvent*); + void wheelEvent(QWheelEvent*); + virtual void paintEvent(QPaintEvent*); + + signals: + void mouseWheel(QWheelEvent*); + + public: + TrackListWidget(QWidget* parent = 0); + }; + +//--------------------------------------------------------- +// Arranger +//--------------------------------------------------------- + +class Arranger : public QWidget { + Q_OBJECT + + QAction* infoDockAction; + QAction* mixerDockAction; + + TrackInfo* trackInfos[Track::TRACK_TYPES]; + QWidget* zeroTrackInfo; + Tool tool; + QWidget* trackList; + PartCanvas* canvas; + TLayout* tl; // tracklist layout + TrackListWidget* tlsv; + TlsvLayout* tlsvLayout; + QDialog* configTrackEditor; + QStackedWidget* trackInfo; + QScrollArea* infoView; + Track* _curTrack; // current selected track + SimpleButton* gmute; + SimpleButton* gsolo; + SimpleButton* gar; + SimpleButton* gaw; + Strip* strip; + QStackedWidget* info; + + Splitter* split; + QDockWidget* infoDock; + QDockWidget* mixerDock; + + int startH; // start value for resize track height + + bool trackInfoVisible; + bool mixerStripVisible; + + void updateIndex(); + TrackInfo* createTrackInfo(); + int tlIndex(Track*) const; + int tlIndex(ArrangerTrack* t) const; + bool initSubtrack(Track* t, ArrangerTrack*); + ArrangerTrack* atrack(int idx); + void insertTrack1(Track*); + + private slots: + void startDrag(int idx); + void drag(int idx, int); + void setTLViewPos(int, int); + void appendSubtrack(TLWidget*); + void removeSubtrack(TLSWidget*); + void configTrackList(); + void toggleTrackInfo(bool); + void toggleMixerStrip(bool); + void setGMute(); + void setGSolo(); + void setGar(); + void setGaw(); + void offGMute(); + void offGSolo(); + void offGar(); + void offGaw(); + void setSelectedTrack(Track*); + void moveTrack(Track* src, Track* dst); + void kbdMovementUpdate(Track* t, Part* p); + void mouseWheel(QWheelEvent*); + void setPos(int, const AL::Pos&); + void addMarker(const AL::Pos&); + void removeMarker(const AL::Pos&); + + public slots: + void insertTrack(Track*); + void removeTrack(Track*); + void setTool(int t); + void updateConfiguration(); + void startLoadSong(); + + signals: + void configChanged(); + void toolChanged(int); + void editPart(Part*); + void cursorPos(const AL::Pos&,bool); + + public: + Arranger(QMainWindow* parent = 0); + void readStatus(QDomNode); + void writeStatus(Xml&); + Track* curTrack() const { return _curTrack; } + void endLoadSong(); + Strip* getStrip() const { return strip; } + + protected: + virtual void keyPressEvent(QKeyEvent* e); + }; + +#endif + diff --git a/muse/muse/arranger/CMakeLists.txt b/muse/muse/arranger/CMakeLists.txt deleted file mode 100644 index b58f6114..00000000 --- a/muse/muse/arranger/CMakeLists.txt +++ /dev/null @@ -1,60 +0,0 @@ -#============================================================================= -# MusE -# Linux Music Editor -# $Id:$ -# -# Copyright (C) 2002-2006 by Werner Schweer and others -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2. -# -# This program 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 this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -#============================================================================= - -QT4_WRAP_CPP ( arranger_mocs - arranger.h - canvas.h - configtrack.h - partdrag.h - tllineedit.h - tlswidget.h - tlwidget.h - trackdrag.h - trackinfo.h - ) - -QT4_WRAP_UI ( arranger_ui_headers - configtrack.ui - midiportinfo.ui - miditrackinfo.ui - ) - -add_library ( arranger STATIC - ${arranger_ui_headers} - ${arranger_mocs} - selectfilter.h - tlwlayout.h - trelement.h - arranger.cpp - canvas.cpp - configtrack.cpp - partdrag.cpp - tllineedit.cpp - tlswidget.cpp - tlwidget.cpp - tlwlayout.cpp - trackdrag.cpp - trackinfo.cpp - ) - -set_target_properties( arranger - PROPERTIES COMPILE_FLAGS "-include ${PROJECT_BINARY_DIR}/all.h" - ) - diff --git a/muse/muse/arranger/arranger.cpp b/muse/muse/arranger/arranger.cpp deleted file mode 100644 index 7b4be381..00000000 --- a/muse/muse/arranger/arranger.cpp +++ /dev/null @@ -1,1382 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#include "song.h" -#include "muse.h" -#include "arranger.h" -#include "tlwidget.h" -#include "tlswidget.h" -#include "icons.h" -#include "widgets/simplebutton.h" -#include "configtrack.h" -#include "canvas.h" -#include "widgets/utils.h" -#include "widgets/splitter.h" -#include "astrip.h" -#include "mstrip.h" -#include "audio.h" -#include "shortcuts.h" -#include "trackinfo.h" -#include "midictrl.h" -#include "gconfig.h" -#include "part.h" - -//--------------------------------------------------------- -// TrElement elements -// list of available track gui elements -//--------------------------------------------------------- - -const TrElement trElements[] = { - TrElement(TR_NAME, 1, "trackname", -1), - TrElement(TR_RECORD, 0, "record", - Track::M_MIDI | Track::M_AUDIO_OUTPUT | Track::M_WAVE), - TrElement(TR_OFF, 2, "off", - Track::M_AUDIO_OUTPUT - | Track::M_AUDIO_GROUP - | Track::M_WAVE - | Track::M_AUDIO_INPUT - | Track::M_AUDIO_SOFTSYNTH), - TrElement(TR_DRUMMAP, 2, "use drum map", Track::M_MIDI), - TrElement(TR_MUTE, 3, "mute", -1), - TrElement(TR_SOLO, 3, "solo", -1), - TrElement(TR_MONITOR, 3, "monitor", - Track::M_MIDI | Track::M_WAVE), - TrElement(TR_AREAD, 4, "automation read", - -1 & ~(Track::M_MIDI_IN | Track::M_MIDI)), - TrElement(TR_AWRITE, 4, "automation write", - -1 & ~(Track::M_MIDI_IN | Track::M_MIDI)), - TrElement(TR_OCHANNEL, 5, "output channel", Track::M_MIDI), - TrElement(TR_INSTRUMENT, 6, "instrument", Track::M_MIDI_OUT), - TrElement(TR_PATCH, 7, "patch", Track::M_MIDI), - }; - -const int nTrElements = sizeof(trElements)/sizeof(*trElements); - -TrGroupList glist[Track::TRACK_TYPES]; - -extern void populateAddTrack(QMenu*); - -//--------------------------------------------------------- -// sizeHint -//--------------------------------------------------------- - -QSize InfoStack::sizeHint() const - { - return QSize(infoWidth, height()); - } - -//--------------------------------------------------------- -// TLayout -// simple layout for trackList -//--------------------------------------------------------- - -class TLayout : public QLayout { - QList itemList; - - public: - TLayout() {} - ~TLayout(); - - void addItem(QLayoutItem* item); - void insertWidget(int index, QWidget* item); - Qt::Orientations expandingDirections() const { return 0; } - bool hasHeightForWidth() const { return false; } - int count() const { return itemList.size(); } - void setGeometry(const QRect &rect); - QSize sizeHint() const { return ((QWidget*)parent())->size(); } - QLayoutItem *itemAt(int index) const { return itemList.value(index); } - QLayoutItem *takeAt(int idx) { - return idx >= 0 && idx < itemList.size() ? itemList.takeAt(idx) : 0; - } - void clear() { - QLayoutItem* child; - while ((child = takeAt(0)) != 0) { - delete child; - } - } - }; - -//--------------------------------------------------------- -// TLayout -//--------------------------------------------------------- - -TLayout::~TLayout() - { - QLayoutItem* child; - while ((child = takeAt(0)) != 0) - delete child; - } - -//--------------------------------------------------------- -// insertWidget -//--------------------------------------------------------- - -void TLayout::insertWidget(int index, QWidget* item) - { - if (item->parent() == 0) - item->setParent((QWidget*)parent()); - itemList.insert(index, new QWidgetItem(item)); - update(); - } - -//--------------------------------------------------------- -// addItem -//--------------------------------------------------------- - -void TLayout::addItem(QLayoutItem* item) - { - itemList.append(item); - update(); - } - -//--------------------------------------------------------- -// setGeometry -//--------------------------------------------------------- - -void TLayout::setGeometry(const QRect& r) - { - int y = r.y(); - int n = itemList.size(); - int width = r.width(); // ((QWidget*)parent())->width(); - for (int i = 0; i < n; ++i) { - QLayoutItem *item = itemList.at(i); - QWidget* w = item->widget(); - int h = w->height(); - w->setGeometry(0, y, width, h); - y += h; - } - } - -//--------------------------------------------------------- -// TlsvLayout -//--------------------------------------------------------- - -class TlsvLayout : public QLayout { - QList itemList; - int dx, dy; - - public: - TlsvLayout() { - dx = 0; - dy = 0; - } - ~TlsvLayout(); - - void setOffset(int x, int y) { - dx = x; - dy = y; - } - void addItem(QLayoutItem* item); - void insertWidget(int index, QWidget* item); - Qt::Orientations expandingDirections() const { return 0; } - bool hasHeightForWidth() const { return false; } - int count() const { return itemList.size(); } - void setGeometry(const QRect &rect); - QSize sizeHint() const { return ((QWidget*)parent())->size(); } - QLayoutItem *itemAt(int index) const { return itemList.value(index); } - QLayoutItem *takeAt(int idx) { - return idx >= 0 && idx < itemList.size() ? itemList.takeAt(idx) : 0; - } - }; - -//--------------------------------------------------------- -// TlsvLayout -//--------------------------------------------------------- - -TlsvLayout::~TlsvLayout() - { - QLayoutItem* child; - while ((child = takeAt(0)) != 0) - delete child; - } - -//--------------------------------------------------------- -// insertWidget -//--------------------------------------------------------- - -void TlsvLayout::insertWidget(int index, QWidget* item) - { - if (item->parent() == 0) - item->setParent((QWidget*)parent()); - itemList.insert(index, new QWidgetItem(item)); - update(); - } - -//--------------------------------------------------------- -// addItem -//--------------------------------------------------------- - -void TlsvLayout::addItem(QLayoutItem* item) - { - itemList.append(item); - update(); - } - -//--------------------------------------------------------- -// setGeometry -//--------------------------------------------------------- - -void TlsvLayout::setGeometry(const QRect& r) - { - QLayoutItem *item = itemList.at(0); - QWidget* w = item->widget(); - w->setGeometry(dx, dy, r.width(), w->height()); - } - -//--------------------------------------------------------- -// newAddTrackMenu -//--------------------------------------------------------- - -QMenu* newAddTrackMenu(QWidget* parent) - { - QMenu* menu = new QMenu(parent); - populateAddTrack(menu); - return menu; - } - -//--------------------------------------------------------- -// Arranger -//--------------------------------------------------------- - -Arranger::Arranger(QMainWindow* parent) - : QWidget(parent) - { -// setFocusPolicy(Qt::StrongFocus); - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - - for (int i = 0; i < Track::TRACK_TYPES; ++i) - trackInfos[i] = 0; - - zeroTrackInfo = 0; - _curTrack = 0; - strip = 0; - info = 0; - tool = PointerTool; - - for (int tt = 0; tt < Track::TRACK_TYPES; ++tt) { - int gn = 0; - TrElementList group; - for (int i = 0; i < nTrElements; ++i) { - if (!(trElements[i].trackMask & (1<setSpacing(0); - ml->setMargin(0); - setLayout(ml); - - infoDock = new QDockWidget(tr("TrackInfo")); - infoDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); - infoDockAction = infoDock->toggleViewAction(); - - mixerDock = new QDockWidget(tr("")); - mixerDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); - mixerDockAction = mixerDock->toggleViewAction(); - - parent->setDockNestingEnabled(true); - - parent->addDockWidget(Qt::LeftDockWidgetArea, infoDock, Qt::Horizontal); - parent->addDockWidget(Qt::LeftDockWidgetArea, mixerDock, Qt::Horizontal); - - infoView = new QScrollArea; - infoView->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); - - infoDock->setWidget(infoView); - infoView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - - trackInfo = new InfoStack(); - infoView->setWidget(trackInfo); - infoView->setWidgetResizable(true); - - trackInfoVisible = false; - mixerStripVisible = false; - - infoDock->setVisible(false); - mixerDock->setVisible(false); - - connect(infoDockAction, SIGNAL(toggled(bool)), SLOT(toggleTrackInfo(bool))); - connect(mixerDockAction, SIGNAL(toggled(bool)), SLOT(toggleMixerStrip(bool))); - - tlsv = new TrackListWidget; - tlsv->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); - tlsvLayout = new TlsvLayout; - tlsv->setLayout(tlsvLayout); - trackList = new QWidget; - trackList->setAttribute(Qt::WA_StaticContents); - trackList->setMouseTracking(true); - - tlsv->layout()->addWidget(trackList); - tl = new TLayout; - trackList->setLayout(tl); - - // - // Toolbox - // - QHBoxLayout* ttoolsLayout = new QHBoxLayout; - ttoolsLayout->setMargin(1); - ttoolsLayout->setSpacing(1); - - SimpleButton* configButton = new SimpleButton(configIcon, configIcon); - configButton->setAutoRaise(true); - configButton->setToolTip(tr("Config Tracklist")); - configButton->setFixedHeight(rulerHeight-4); - connect(configButton, SIGNAL(clicked()), SLOT(configTrackList())); - ttoolsLayout->addWidget(configButton); - ttoolsLayout->addStretch(100); - - gmute = newMuteButton(); - gmute->setFixedWidth(rulerHeight); - gmute->setToolTip(tr("all mute off")); - gmute->setFixedHeight(rulerHeight-4); - ttoolsLayout->addWidget(gmute); - setGMute(); - connect(song, SIGNAL(muteChanged(Track*,bool)), SLOT(setGMute())); - connect(gmute, SIGNAL(clicked(bool)), SLOT(offGMute())); - - gsolo = newSoloButton(); - gsolo->setFixedWidth(rulerHeight); - gsolo->setToolTip(tr("all solo off")); - gsolo->setFixedHeight(rulerHeight-4); - ttoolsLayout->addWidget(gsolo); - setGSolo(); - connect(song, SIGNAL(soloChanged(Track*,bool)), SLOT(setGSolo())); - connect(gsolo, SIGNAL(clicked(bool)), SLOT(offGSolo())); - - gar = newAutoReadButton(); - gar->setFixedWidth(rulerHeight); - gar->setToolTip(tr("all autoRead off")); - gar->setFixedHeight(rulerHeight-4); - ttoolsLayout->addWidget(gar); - setGar(); - connect(song, SIGNAL(autoReadChanged(Track*,bool)), SLOT(setGar())); - connect(gar, SIGNAL(clicked(bool)), SLOT(offGar())); - - gaw = newAutoWriteButton(); - gaw->setFixedWidth(rulerHeight); - gaw->setToolTip(tr("all autoWrite off")); - gaw->setFixedHeight(rulerHeight-4); - ttoolsLayout->addWidget(gaw); - setGaw(); - connect(song, SIGNAL(autoWriteChanged(Track*,bool)), SLOT(setGaw())); - connect(gaw, SIGNAL(clicked(bool)), SLOT(offGaw())); - - QHBoxLayout* infoboxLayout = new QHBoxLayout; - infoboxLayout->setMargin(1); - infoboxLayout->setSpacing(1); - - SimpleButton* tifButton = new SimpleButton(QString()); - tifButton->setCheckable(true); - tifButton->setFixedSize(infoHeight-2, infoHeight); - tifButton->setDefaultAction(infoDockAction); - infoDockAction->setText(tr("i")); - infoDockAction->setToolTip(tr("Show Track Info")); - infoboxLayout->addWidget(tifButton); - - SimpleButton* mstButton = new SimpleButton(QString()); - mstButton->setCheckable(true); - mstButton->setFixedSize(infoHeight-2, infoHeight); - mstButton->setDefaultAction(mixerDockAction); - mixerDockAction->setText(tr("m")); - mixerDockAction->setToolTip(tr("Show Mixer Strip")); - infoboxLayout->addWidget(mstButton); - - infoboxLayout->addStretch(100); - - split = new Splitter(Qt::Horizontal); - split->setOpaqueResize(true); - split->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - QWidget* tw = new QWidget; - split->addWidget(tw); - QVBoxLayout* trackListGrid = new QVBoxLayout; - trackListGrid->setMargin(0); - trackListGrid->setSpacing(0); - tw->setLayout(trackListGrid); - - trackListGrid->addLayout(ttoolsLayout); - QFrame* ruler = hLine(0); - ruler->setLineWidth(2); - trackListGrid->addWidget(ruler); - trackListGrid->addWidget(tlsv, 100); - trackListGrid->addLayout(infoboxLayout); - - // - // canvas widget - // - canvas = new PartCanvas; - canvas->setCornerWidget(new QSizeGrip(canvas)); - split->addWidget(canvas); - split->setStretchFactor(1, 100); - canvas->setTool(tool); - canvas->verticalScrollBar()->setSingleStep(minTrackHeight/2); - - connect(tlsv, SIGNAL(mouseWheel(QWheelEvent*)), SLOT(mouseWheel(QWheelEvent*))); - connect(song, SIGNAL(posChanged(int,const AL::Pos&,bool)), canvas, SLOT(setLocatorPos(int,const AL::Pos&,bool))); - connect(song, SIGNAL(lenChanged(const AL::Pos&)), canvas, SLOT(setEndPos(const AL::Pos&))); - connect(song, SIGNAL(tempoChanged()), canvas, SLOT(tempoChanged())); - connect(canvas, SIGNAL(kbdMovementUpdate(Track*, Part*)), SLOT(kbdMovementUpdate(Track*, Part*))); - connect(muse, SIGNAL(rasterChanged(int)), canvas, SLOT(setRaster(int))); - connect(canvas, SIGNAL(cursorPos(const AL::Pos&,bool)), SIGNAL(cursorPos(const AL::Pos&,bool))); - connect(canvas, SIGNAL(contentsMoving(int,int)), SLOT(setTLViewPos(int,int))); - connect(canvas, SIGNAL(posChanged(int,const AL::Pos&)), SLOT(setPos(int,const AL::Pos&))); - - connect(canvas, SIGNAL(createLRPart(Track*)), song, SLOT(cmdCreateLRPart(Track*))); - connect(canvas, SIGNAL(doubleClickPart(Part*)), SIGNAL(editPart(Part*))); - connect(canvas, SIGNAL(startEditor(Part*,int)), muse, SLOT(startEditor(Part*,int))); - connect(canvas, SIGNAL(partChanged(Part*,unsigned,unsigned)), - song, SLOT(cmdChangePart(Part*,unsigned,unsigned))); - connect(canvas, SIGNAL(addMarker(const AL::Pos&)), SLOT(addMarker(const AL::Pos&))); - connect(canvas, SIGNAL(removeMarker(const AL::Pos&)), SLOT(removeMarker(const AL::Pos&))); - - layout()->addWidget(split); - - connect(muse, SIGNAL(configChanged()), SLOT(updateConfiguration())); - connect(song, SIGNAL(trackSelectionChanged(Track*)), SLOT(setSelectedTrack(Track*))); - connect(song, SIGNAL(trackRemoved(Track*)), SLOT(removeTrack(Track*))); - connect(song, SIGNAL(trackAdded(Track*,int)), SLOT(insertTrack(Track*))); - connect(muse, SIGNAL(startLoadSong()), SLOT(startLoadSong())); - } - -//--------------------------------------------------------- -// setPos -//--------------------------------------------------------- - -void Arranger::setPos(int idx, const AL::Pos& pos) - { - song->setPos(idx, pos.snaped(muse->raster())); - } - -//--------------------------------------------------------- -// setTLViewPos -//--------------------------------------------------------- - -void Arranger::setTLViewPos(int /*x*/, int y) - { -#if 1 - int dy = y + trackList->y(); - tlsv->scroll(0, -dy); -#else - trackList->setGeometry(0, -y, trackList->width(), trackList->height()); -#endif - tlsvLayout->setOffset(0, -y); - } - -//--------------------------------------------------------- -// tlIndex -//--------------------------------------------------------- - -int Arranger::tlIndex(Track* t) const - { - const TrackList* stl = song->tracks(); - - int idx = 0; - for (ciTrack i = stl->begin(); i != stl->end(); ++i, ++idx) { - if (*i == t) - break; - ArrangerTrack* at = &(*i)->arrangerTrack; - if (at->tw == 0) - continue; - idx += (*i)->subtracks.size(); - } - return idx; - } - -int Arranger::tlIndex(ArrangerTrack* t) const - { - TrackList* stl = song->tracks(); - - int idx = 0; - for (ciTrack i = stl->begin(); i != stl->end(); ++i, ++idx) { - ArrangerTrack* at = &(*i)->arrangerTrack; - if (at->tw == 0) - continue; - ArrangerTrackList& atl = (*i)->subtracks; - for (iArrangerTrack k = atl.begin(); k != atl.end(); ++k) { - ++idx; - if (*k == t) - return idx; - } - } - return -1; // crash - } - -//--------------------------------------------------------- -// insertTrack -//--------------------------------------------------------- - -void Arranger::insertTrack1(Track* t) - { - int idx = tlIndex(t); - //------------------------- - // track list widget - //------------------------- - - TLWidget* tw = new TLWidget(t, &glist[t->type()]); - tw->setFixedHeight(t->arrangerTrack.h); - tl->insertWidget(idx, tw); - tw->show(); // needed if song is reloaded - - connect(tw, SIGNAL(plusClicked(TLWidget*)), SLOT(appendSubtrack(TLWidget*))); - connect(tw, SIGNAL(moveTrack(Track*,Track*)), SLOT(moveTrack(Track*,Track*))); - connect(this, SIGNAL(configChanged()), tw, SLOT(configChanged())); - connect(tw, SIGNAL(drag(int, int)), SLOT(drag(int,int))); - connect(tw, SIGNAL(startDrag(int)), SLOT(startDrag(int))); - connect(t, SIGNAL(partsChanged()), canvas->widget(), SLOT(update())); - - ArrangerTrack* at = &(t->arrangerTrack); - at->tw = tw; - } - -void Arranger::insertTrack(Track* t) - { - insertTrack1(t); - t->arrangerTrack.tw->show(); - updateIndex(); - if (_curTrack == 0) - setSelectedTrack(_curTrack); - } - -//--------------------------------------------------------- -// removeTrack -//--------------------------------------------------------- - -void Arranger::removeTrack(Track* t) - { - ArrangerTrack* at = &t->arrangerTrack; - if (at->tw == 0) - return; - - tl->removeWidget(at->tw); - - at->tw->close(); - at->tw = 0; - - for (iArrangerTrack i = t->subtracks.begin(); i != t->subtracks.end(); ++i) { - ArrangerTrack* at = *i; - tl->removeWidget(at->tw); - at->tw->close(); - } - t->subtracks.clear(); - - if (t == _curTrack) { - if (!song->tracks()->isEmpty()) - song->selectTrack(song->tracks()->front()); - } - updateIndex(); - } - -//--------------------------------------------------------- -// drag -//--------------------------------------------------------- - -void Arranger::drag(int trackIdx, int delta) - { - int h = startH + delta; - if (h < minTrackHeight) - h = minTrackHeight; - ArrangerTrack* at = atrack(trackIdx); - at->tw->setFixedHeight(h); - updateIndex(); - } - -//--------------------------------------------------------- -// startDrag -//--------------------------------------------------------- - -void Arranger::startDrag(int trackIdx) - { - ArrangerTrack* at = atrack(trackIdx); - startH = at->tw->height(); - } - -//--------------------------------------------------------- -// TrackListWidget -//--------------------------------------------------------- - -TrackListWidget::TrackListWidget(QWidget* parent) - : QWidget(parent) - { - setAttribute(Qt::WA_NoSystemBackground); - setAttribute(Qt::WA_StaticContents); - } - -//--------------------------------------------------------- -// paintEvent -//--------------------------------------------------------- - -void TrackListWidget::paintEvent(QPaintEvent* ev) - { - QPainter p(this); - p.eraseRect(ev->rect()); - } - -//--------------------------------------------------------- -// mousePressEvent -//--------------------------------------------------------- - -void TrackListWidget::mousePressEvent(QMouseEvent* ev) - { - if (ev->button() == Qt::RightButton) { - QMenu* menu = newAddTrackMenu(this); - menu->exec(ev->globalPos()); - } - } - -//--------------------------------------------------------- -// wheelEvent -//--------------------------------------------------------- - -void TrackListWidget::wheelEvent(QWheelEvent* e) - { - emit mouseWheel(e); - } - -//--------------------------------------------------------- -// mouseWheel -// get redirected mouse wheel events from TrackListWidget -//--------------------------------------------------------- - -void Arranger::mouseWheel(QWheelEvent* e) - { - if (e->orientation() != Qt::Vertical) - return; - QScrollBar* sb = canvas->verticalScrollBar(); - int step = qMin(QApplication::wheelScrollLines() * sb->singleStep(), sb->pageStep()); - if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier)) - step = sb->pageStep(); - int offset = e->delta() * step / 120; - if (sb->invertedControls()) - offset = -offset; - if (qAbs(offset) < 1) - return; - sb->setValue(sb->value() + offset); - e->accept(); - } - -//--------------------------------------------------------- -// appendSubtrack -// the user requests a new controller subtrack -//--------------------------------------------------------- - -void Arranger::appendSubtrack(TLWidget* trackWidget) - { - Track* t = trackWidget->track(); - - ArrangerTrack* at = new ArrangerTrack; - at->h = minTrackHeight; - at->ctrl = CTRL_NO_CTRL; - t->subtracks.push_back(at); - if(initSubtrack(t, at)==true) { - updateIndex(); - } - else { - t->subtracks.remove(at); - delete at; - } - } - -//--------------------------------------------------------- -// initSubtrack -//--------------------------------------------------------- - -bool Arranger::initSubtrack(Track* t, ArrangerTrack* at) - { - TLSWidget* tw = new TLSWidget(t, at, canvas); - tw->setFixedHeight(at->h); - - if(tw->setCtrl(at->ctrl) == true) { - tl->insertWidget(tlIndex(at), tw); - at->tw = tw; - connect(tw, SIGNAL(minusClicked(TLSWidget*)), SLOT(removeSubtrack(TLSWidget*))); - connect(tw, SIGNAL(controllerChanged(int)), canvas->widget(), SLOT(update())); - connect(tw, SIGNAL(drag(int, int)), SLOT(drag(int,int))); - connect(tw, SIGNAL(startDrag(int)), SLOT(startDrag(int))); - tw->show(); - } - else { - delete tw; - return false; - } - return true; - } - -//--------------------------------------------------------- -// removeSubtrack -//--------------------------------------------------------- - -void Arranger::removeSubtrack(TLSWidget* w) - { - Track* t = w->track(); - for (iArrangerTrack it = t->subtracks.begin(); it != t->subtracks.end(); ++it) { - ArrangerTrack* at = *it; - if (at->tw == w) { - tl->removeWidget(at->tw); -// at->tw->close(); - delete at->tw; - t->subtracks.erase(it); - delete at; - break; - } - } - updateIndex(); - } - -//--------------------------------------------------------- -// configTrackList -//--------------------------------------------------------- - -void Arranger::configTrackList() - { - if (configTrackEditor == 0) { - configTrackEditor = new ConfigTrackList(this); - connect(configTrackEditor, SIGNAL(trackConfigChanged()), SIGNAL(configChanged())); - } - configTrackEditor->show(); - } - -//--------------------------------------------------------- -// atrack -//--------------------------------------------------------- - -ArrangerTrack* Arranger::atrack(int idx) - { - int k = 0; - TrackList* stl = song->tracks(); - for (iTrack i = stl->begin(); i != stl->end(); ++i) { - ArrangerTrack* at = &(*i)->arrangerTrack; - if (idx == k) - return at; - ++k; - for (iArrangerTrack it = (*i)->subtracks.begin(); it != (*i)->subtracks.end(); ++it) { - ArrangerTrack* t = *it; - if (idx == k) - return t; - ++k; - } - } - return 0; - } - -//--------------------------------------------------------- -// updateIndex -// update vertical scrollbar & index values -//--------------------------------------------------------- - -void Arranger::updateIndex() - { - int idx = 0; - int h = 2 * defaultTrackHeight; // always show room for at least two - // tracks at end of list - - TrackList* stl = song->tracks(); - for (iTrack i = stl->begin(); i != stl->end(); ++i) { - ArrangerTrack* at = &(*i)->arrangerTrack; - if (at->tw == 0) - continue; - ((TLWidget*)at->tw)->setIdx(idx); - h += at->tw->height(); - ++idx; - for (iArrangerTrack it = (*i)->subtracks.begin(); it != (*i)->subtracks.end(); ++it) { - ArrangerTrack* t = *it; - if (t->tw == 0) - continue; - ((TLSWidget*)t->tw)->setIdx(idx); - h += t->tw->height(); - ++idx; - } - } - setGMute(); - setGSolo(); - setGar(); - setGaw(); - canvas->setVSize(h); - trackList->setFixedHeight(h + 32); - canvas->widget()->update(); - QPoint p(canvas->getWPos()); - setTLViewPos(0, p.y()); - } - -//--------------------------------------------------------- -// toggleTrackInfo -//--------------------------------------------------------- - -void Arranger::toggleTrackInfo(bool val) - { - trackInfoVisible = val; - if (trackInfoVisible) { - if (_curTrack == 0) { - if (zeroTrackInfo == 0) { - zeroTrackInfo = new QWidget(this); - trackInfo->addWidget(zeroTrackInfo); - } - trackInfo->setCurrentWidget(zeroTrackInfo); - - return; - } - Track::TrackType t = _curTrack->type(); - TrackInfo* w = trackInfos[t]; - if (w == 0) { - w = trackInfos[t] = createTrackInfo(); - trackInfo->addWidget(w); - } - w->init(_curTrack); - trackInfo->setCurrentWidget(w); - } -// infoDock->layout()->invalidate(); -// infoDock->layout()->update(); - } - -//--------------------------------------------------------- -// toggleMixerStrip -//--------------------------------------------------------- - -void Arranger::toggleMixerStrip(bool val) - { - mixerStripVisible = val; - if (mixerStripVisible && _curTrack) { - if (strip && _curTrack != strip->getTrack()) { - strip->close(); - strip = 0; - } - if (!strip) { - switch(_curTrack->type()) { - case Track::MIDI_IN: - strip = new MidiInPortStrip(0, (MidiInPort*)_curTrack, false); - break; - case Track::MIDI_OUT: - strip = new MidiOutPortStrip(0, (MidiOutPort*)_curTrack, false); - break; - case Track::MIDI_SYNTI: - strip = new MidiSyntiStrip(0, (MidiSynti*)_curTrack, false); - break; - case Track::MIDI: - strip = new MidiStrip(0, (MidiTrack*)_curTrack, false); - break; - default: - strip = new AudioStrip(0, (AudioTrack*)_curTrack, false); - break; - } - // - // it looks like the dock widget has a minimum - // width - strip->setFixedWidth(STRIP_WIDTH + 10); - mixerDock->setWidget(strip); - } - } - else { - if (strip) { - strip->close(); - strip = 0; - } - } - } - -//--------------------------------------------------------- -// startLoadSong -//--------------------------------------------------------- - -void Arranger::startLoadSong() - { - if (strip) - strip->close(); - strip = 0; - - TrackList* stl = song->tracks(); - for (iTrack i = stl->begin(); i != stl->end(); ++i) { - ArrangerTrack* at = &(*i)->arrangerTrack; - tl->removeWidget(at->tw); - at->tw->close(); - delete at->tw; - at->tw = 0; - for (iArrangerTrack it = (*i)->subtracks.begin(); it != (*i)->subtracks.end(); ++it) { - ArrangerTrack* at = *it; - tl->removeWidget(at->tw); - at->tw->close(); - delete at->tw; - } - (*i)->subtracks.clear(); - } - _curTrack = 0; - } - -//--------------------------------------------------------- -// endLoadSong -// create track list widgets -//--------------------------------------------------------- - -void Arranger::endLoadSong() - { - TrackList* stl = song->tracks(); - - for (iTrack i = stl->begin(); i != stl->end(); ++i) { - Track* t = *i; - insertTrack1(t); - for (iArrangerTrack i = t->subtracks.begin(); i != t->subtracks.end(); ++i) { - initSubtrack(t, *i); - } - } - updateIndex(); - setSelectedTrack(song->selectedTrack()); - infoDock->setVisible(trackInfoVisible); - mixerDock->setVisible(mixerStripVisible); - } - -//--------------------------------------------------------- -// updateConfiguration -//--------------------------------------------------------- - -void Arranger::updateConfiguration() - { - if (config.canvasUseBgPixmap) { - canvas->setCanvasBackground(QPixmap(config.canvasBgPixmap)); - } - else - canvas->setCanvasBackground(config.canvasBgColor); -//TD canvas->setShowGrid(config.canvasShowGrid); -//TD update(); - } - -//--------------------------------------------------------- -// readStatus -//--------------------------------------------------------- - -void Arranger::readStatus(QDomNode node) - { - TrackList* tl = song->tracks(); - iTrack it = tl->begin(); - - QPoint wpos; - double xmag = 0.05; - double ymag = 1.0; - - for (; !node.isNull(); node = node.nextSibling()) { - QDomElement e = node.toElement(); - QString tag(e.tagName()); - QString s = e.text(); - int i = s.toInt(); - if (tag == "info") - trackInfoVisible = i; - else if (tag == "strip") - mixerStripVisible = i; - else if (tag == "TrackConf") { - } - else if (tag == "hmag") - xmag = s.toDouble(); - else if (tag == "vmag") - ymag = s.toDouble(); - else if (tag == "hpos") - wpos.setX(i); - else if (tag == "vpos") - wpos.setY(i); - else if (tag == "raster") { - muse->initRaster(i); - canvas->setRaster(i); - } - else if (tag == "splitter") { - split->readStatus(node); - QList sizes = split->sizes(); - split->setSizes(sizes); - } - else - printf("Arranger: unknown tag %s\n", tag.toLatin1().data()); - } - canvas->setMag(xmag, ymag); - canvas->setWPos(wpos); - } - -//--------------------------------------------------------- -// writeStatus -//--------------------------------------------------------- - -void Arranger::writeStatus(Xml& xml) - { - xml.stag("arranger"); - - for (int i = 0; i < Track::TRACK_TYPES; ++i) { - TrGroupList* gl = &glist[i]; - xml.stag(QString("TrackConf type=\"%1\"").arg(i)); - for (iTrGroup ig = gl->begin(); ig != gl->end(); ++ig) { - TrElementList& el = *ig; - xml.stag("group"); - for (iTrElement ie = el.begin(); ie != el.end(); ++ie) - xml.tagE(QString("element id=\"%1\"").arg((*ie)->id)); - xml.etag("group"); - } - xml.etag("TrackConf"); - } - xml.tag("info", trackInfoVisible); - xml.tag("strip", mixerStripVisible); - xml.tag("hmag", canvas->xmag()); - xml.tag("vmag", canvas->ymag()); - xml.tag("hpos", canvas->getWPos().x()); - xml.tag("vpos", canvas->getWPos().y()); - xml.tag("raster", muse->raster()); - split->writeStatus("splitter", xml); - xml.etag("arranger"); - } - -//--------------------------------------------------------- -// setGMute -//--------------------------------------------------------- - -void Arranger::setGMute() - { - TrackList* tl = song->tracks(); - bool mute = false; - for (iTrack i = tl->begin(); i != tl->end(); ++i) { - if ((*i)->mute()) { - mute = true; - break; - } - } - gmute->setChecked(mute); - } - -//--------------------------------------------------------- -// setGSolo -//--------------------------------------------------------- - -void Arranger::setGSolo() - { - TrackList* tl = song->tracks(); - bool solo = false; - for (iTrack i = tl->begin(); i != tl->end(); ++i) { - if ((*i)->solo()) { - solo = true; - break; - } - } - gsolo->setChecked(solo); - } - -//--------------------------------------------------------- -// setGar -//--------------------------------------------------------- - -void Arranger::setGar() - { - TrackList* tl = song->tracks(); - bool ar = false; - for (iTrack i = tl->begin(); i != tl->end(); ++i) { - if ((*i)->autoRead()) { - ar = true; - break; - } - } - if (ar == false) { - MidiTrackList* cl = song->midis(); - for (iMidiTrack i = cl->begin(); i != cl->end(); ++i) { - if ((*i)->autoRead()) { - ar = true; - break; - } - } - } - gar->setChecked(ar); - } - -//--------------------------------------------------------- -// setGaw -//--------------------------------------------------------- - -void Arranger::setGaw() - { - TrackList*tl = song->tracks(); - bool aw = false; - for (iTrack i = tl->begin(); i != tl->end(); ++i) { - if ((*i)->autoWrite()) - aw = true; - } - if (aw == false) { - MidiTrackList* cl = song->midis(); - for (iMidiTrack i = cl->begin(); i != cl->end(); ++i) { - if ((*i)->autoWrite()) { - aw = true; - break; - } - } - } - gaw->setChecked(aw); - } - -//--------------------------------------------------------- -// offGMute -//--------------------------------------------------------- - -void Arranger::offGMute() - { - TrackList*tl = song->tracks(); - for (iTrack i = tl->begin(); i != tl->end(); ++i) - song->setMute(*i,false); - gmute->setChecked(false); - } - -//--------------------------------------------------------- -// offGSolo -//--------------------------------------------------------- - -void Arranger::offGSolo() - { - TrackList*tl = song->tracks(); - for (iTrack i = tl->begin(); i != tl->end(); ++i) - song->setSolo(*i, false); - gsolo->setChecked(false); - } - -//--------------------------------------------------------- -// offGar -//--------------------------------------------------------- - -void Arranger::offGar() - { - TrackList*tl = song->tracks(); - for (iTrack i = tl->begin(); i != tl->end(); ++i) - song->setAutoRead(*i, false); - MidiTrackList* cl = song->midis(); - for (iMidiTrack i = cl->begin(); i != cl->end(); ++i) - song->setAutoRead(*i, false); - gar->setChecked(false); - } - -//--------------------------------------------------------- -// offGaw -//--------------------------------------------------------- - -void Arranger::offGaw() - { - TrackList*tl = song->tracks(); - for (iTrack i = tl->begin(); i != tl->end(); ++i) - song->setAutoWrite(*i, false); - MidiTrackList* cl = song->midis(); - for (iMidiTrack i = cl->begin(); i != cl->end(); ++i) - song->setAutoWrite(*i, false); - gaw->setChecked(false); - } - -//--------------------------------------------------------- -// setTool -//--------------------------------------------------------- - -void Arranger::setTool(int t) - { - tool = Tool(t); - canvas->setTool(tool); - } - -//--------------------------------------------------------- -// setSelectedTrack -//--------------------------------------------------------- - -void Arranger::setSelectedTrack(Track* t) - { - _curTrack = t; - toggleTrackInfo(trackInfoVisible); - toggleMixerStrip(mixerStripVisible); - } - -//--------------------------------------------------------- -// moveTrack -// move src before dst -//--------------------------------------------------------- - -void Arranger::moveTrack(Track* src, Track* dst) - { - audio->msgMoveTrack(src, dst); - tl->clear(); - TrackList* stl = song->tracks(); - for (iTrack i = stl->begin(); i != stl->end(); ++i) { - tl->addWidget((*i)->arrangerTrack.tw); - for (iArrangerTrack it = (*i)->subtracks.begin(); it != (*i)->subtracks.end(); ++it) - tl->addWidget((*it)->tw); - } - tl->setGeometry(((QWidget*)tl->parent())->geometry()); - updateIndex(); - } - -//--------------------------------------------------------- -//! \fn Arranger::keyPressEvent(QKeyEvent* e) -//! \brief Called when a key is pressed -//! @param e The key event -//--------------------------------------------------------- - -void Arranger::keyPressEvent(QKeyEvent* e) - { - printf("Arranger::keyPressEvent\n"); -#if 0 //TODOB - int key = e->key(); - bool keypress_handled = false; - - if (e->modifiers() & Qt::ShiftModifier) - key += Qt::SHIFT; - if (e->modifiers() & Qt::AltModifier) - key += Qt::ALT; - if (e->modifiers() & Qt::ControlModifier) - key += Qt::CTRL; - - if (shortcutsKbdMovement.isValid()) { - if (key == shortcuts[SHRT_SEL_LEFT].key || key == shortcuts[SHRT_SEL_LEFT_ADD].key) { - keypress_handled = true; - bool add = (key == shortcuts[SHRT_SEL_LEFT_ADD].key); - PartList* parts = shortcutsKbdMovement.track()->parts(); - Part* nextLeft = 0; - - for (iPart i = parts->begin(); i != parts->end(); i++) { - Part* tmp = i->second; - if (!nextLeft) { - if (tmp->tick() < shortcutsKbdMovement.getLpos()) - nextLeft = tmp; - } - else { - if (tmp->tick() > nextLeft->tick() && tmp->tick() < shortcutsKbdMovement.getLpos() ) - nextLeft = tmp; - } - } - if (nextLeft) { - song->selectPart(nextLeft, add); - shortcutsKbdMovement.setPart(nextLeft); - shortcutsKbdMovement.setPos(nextLeft->tick(), nextLeft->tick() + nextLeft->lenTick()); - } - } - else if (key == shortcuts[SHRT_SEL_RIGHT].key || key == shortcuts[SHRT_SEL_RIGHT_ADD].key) { - keypress_handled = true; - bool add = (key == shortcuts[SHRT_SEL_RIGHT_ADD].key); - PartList* parts = shortcutsKbdMovement.track()->parts(); - Part* nextRight = 0; - - for (iPart i = parts->begin(); i != parts->end(); i++) { - Part* tmp = i->second; - if (!nextRight) { - if (tmp->tick() > shortcutsKbdMovement.getLpos()) - nextRight = tmp; - } - else { - if (tmp->tick() < nextRight->tick() && tmp->tick() > shortcutsKbdMovement.getLpos() ) - nextRight = tmp; - } - } - if (nextRight) { - song->selectPart(nextRight, add); - shortcutsKbdMovement.setPart(nextRight); - shortcutsKbdMovement.setPos(nextRight->tick(), nextRight->tick() + nextRight->lenTick()); - } - } - - else if (key == shortcuts[SHRT_SEL_ABOVE].key) { - // TODO - } - else if (key == shortcuts[SHRT_SEL_BELOW].key) { - // TODO - } - } // -- end movement - else { - if (key == shortcuts[SHRT_TOOL_POINTER].key) { - emit toolChanged(PointerTool); - return; - } - else if (key == shortcuts[SHRT_TOOL_PENCIL].key) { - emit toolChanged(PencilTool); - return; - } - else if (key == shortcuts[SHRT_TOOL_RUBBER].key) { - emit toolChanged(RubberTool); - return; - } - else if (key == shortcuts[SHRT_TOOL_LINEDRAW].key) { - emit toolChanged(DrawTool); - return; - } - } - // If we haven't dealt with the keypress, pass it along - if (!keypress_handled) { - e->ignore(); - } -#endif -// e->ignore(); - } - - -/*! - \fn Arranger::kbdMovementUpdate(Track* t, Part* p) - \brief Slot connected to canvaswidget, called when a part is selected - @param t Track the selected part belongs to (null if no part selected) - @param p The selected Part (null if no part selected) - */ -void Arranger::kbdMovementUpdate(Track* t, Part* p) - { - printf("kbdMovementUpdate\n"); -// if (t && p ) { -// // If other track selected: -// if (t != shortcutsKbdMovement.track()) { -// TrackList* stl = song->tracks(); -// for (iTrack i = stl->begin(); i != stl->end(); ++i) { -// if (*i == t) { -// // Set focus and select current track -// t->arrangerTrack.tw->setFocus(); -// song->selectTrack(t); -// } -// } -// } -// shortcutsKbdMovement.setTrack(t); -// shortcutsKbdMovement.setPart(p); -// shortcutsKbdMovement.setPos(p->tick(), p->tick() + p->lenTick()); -// } -// else { // Deselected -// shortcutsKbdMovement.reset(); -// } - } - -//--------------------------------------------------------- -// addMarker -//--------------------------------------------------------- - -void Arranger::addMarker(const AL::Pos& pos) - { - song->addMarker(QString(), pos); - canvas->widget()->update(); - } - -//--------------------------------------------------------- -// removeMarker -//--------------------------------------------------------- - -void Arranger::removeMarker(const AL::Pos& pos) - { - AL::MarkerList* ml = song->marker(); - for (AL::iMarker i = ml->begin(); i != ml->end(); ++i) { - AL::iMarker ni = i; - ++ni; - if (i->second <= pos && (ni == ml->end() || ni->second > pos)) { - song->removeMarker(&(i->second)); - canvas->widget()->update(); - return; - } - } - printf("marker not found\n"); - } diff --git a/muse/muse/arranger/arranger.h b/muse/muse/arranger/arranger.h deleted file mode 100644 index 1c9f6e38..00000000 --- a/muse/muse/arranger/arranger.h +++ /dev/null @@ -1,175 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#ifndef __ARRANGER_H__ -#define __ARRANGER_H__ - -#include "widgets/tools.h" -#include "track.h" - -namespace AL { - class Xml; - class Pos; - }; -using AL::Xml; -class AL::Pos; - -class Track; -class TrackInfo; -class TLWidget; -class TLSWidget; -class PartCanvas; -class Part; -class SimpleButton; -class Strip; -class ArrangerTrack; -class Splitter; -class TlsvLayout; -class TLayout; - -//--------------------------------------------------------- -// InfoStack -//--------------------------------------------------------- - -class InfoStack : public QStackedWidget { - Q_OBJECT; - - virtual QSize sizeHint() const; - - public: - InfoStack() : QStackedWidget() {} - }; - -//--------------------------------------------------------- -// TrackListWidget -//--------------------------------------------------------- - -class TrackListWidget : public QWidget { - Q_OBJECT - - void mousePressEvent(QMouseEvent*); - void wheelEvent(QWheelEvent*); - virtual void paintEvent(QPaintEvent*); - - signals: - void mouseWheel(QWheelEvent*); - - public: - TrackListWidget(QWidget* parent = 0); - }; - -//--------------------------------------------------------- -// Arranger -//--------------------------------------------------------- - -class Arranger : public QWidget { - Q_OBJECT - - QAction* infoDockAction; - QAction* mixerDockAction; - - TrackInfo* trackInfos[Track::TRACK_TYPES]; - QWidget* zeroTrackInfo; - Tool tool; - QWidget* trackList; - PartCanvas* canvas; - TLayout* tl; // tracklist layout - TrackListWidget* tlsv; - TlsvLayout* tlsvLayout; - QDialog* configTrackEditor; - QStackedWidget* trackInfo; - QScrollArea* infoView; - Track* _curTrack; // current selected track - SimpleButton* gmute; - SimpleButton* gsolo; - SimpleButton* gar; - SimpleButton* gaw; - Strip* strip; - QStackedWidget* info; - - Splitter* split; - QDockWidget* infoDock; - QDockWidget* mixerDock; - - int startH; // start value for resize track height - - bool trackInfoVisible; - bool mixerStripVisible; - - void updateIndex(); - TrackInfo* createTrackInfo(); - int tlIndex(Track*) const; - int tlIndex(ArrangerTrack* t) const; - bool initSubtrack(Track* t, ArrangerTrack*); - ArrangerTrack* atrack(int idx); - void insertTrack1(Track*); - - private slots: - void startDrag(int idx); - void drag(int idx, int); - void setTLViewPos(int, int); - void appendSubtrack(TLWidget*); - void removeSubtrack(TLSWidget*); - void configTrackList(); - void toggleTrackInfo(bool); - void toggleMixerStrip(bool); - void setGMute(); - void setGSolo(); - void setGar(); - void setGaw(); - void offGMute(); - void offGSolo(); - void offGar(); - void offGaw(); - void setSelectedTrack(Track*); - void moveTrack(Track* src, Track* dst); - void kbdMovementUpdate(Track* t, Part* p); - void mouseWheel(QWheelEvent*); - void setPos(int, const AL::Pos&); - void addMarker(const AL::Pos&); - void removeMarker(const AL::Pos&); - - public slots: - void insertTrack(Track*); - void removeTrack(Track*); - void setTool(int t); - void updateConfiguration(); - void startLoadSong(); - - signals: - void configChanged(); - void toolChanged(int); - void editPart(Part*); - void cursorPos(const AL::Pos&,bool); - - public: - Arranger(QMainWindow* parent = 0); - void readStatus(QDomNode); - void writeStatus(Xml&); - Track* curTrack() const { return _curTrack; } - void endLoadSong(); - Strip* getStrip() const { return strip; } - - protected: - virtual void keyPressEvent(QKeyEvent* e); - }; - -#endif - diff --git a/muse/muse/arranger/canvas.cpp b/muse/muse/arranger/canvas.cpp deleted file mode 100644 index 614cf3e3..00000000 --- a/muse/muse/arranger/canvas.cpp +++ /dev/null @@ -1,1187 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#include "canvas.h" -#include "al/al.h" -#include "al/sig.h" -#include "gconfig.h" -#include "song.h" -#include "icons.h" -#include "audio.h" -#include "partdrag.h" -#include "muse.h" -#include "midictrl.h" -#include "tlswidget.h" -#include "part.h" -#include "gui.h" - -#include - -static const int partLabelHeight = 13; -static const int handleWidth = 5; -static const int partBorderWidth = 2; - -enum { HIT_NOTHING, HIT_TRACK, HIT_PART, HIT_SUBTRACK }; - -//--------------------------------------------------------- -// PartCanvas -//--------------------------------------------------------- - -PartCanvas::PartCanvas() - : TimeCanvas(TIME_CANVAS) - { - setFocusPolicy(Qt::StrongFocus); - state = S_NORMAL; - _drawBackground = true; - lselected = -1; - starty = -1; - setMarkerList(song->marker()); - rubberBand=NULL; - connect(song, SIGNAL(markerChanged(int)), SLOT(markerChanged(int))); - } - -//--------------------------------------------------------- -// markerChanged -//--------------------------------------------------------- - -void PartCanvas::markerChanged(int val) - { - if (val == Song::MARKER_CUR) - updateRuler(); - } - -//--------------------------------------------------------- -// drawWavePart -// y0 - start of track -// th - track height -// from - x pixel coordinate start drawing -// to - x end drawing -// -// redraw area is QRect(from, y0, to-from, th) -//--------------------------------------------------------- - -void PartCanvas::drawWavePart(QPainter& p, Part* wp, int y0, int th, int from, int to) - { - int h = th/2; - int y = y0 + 1 + h; - int cc = th % 2 ? 0 : 1; - - const Pos pos(pix2pos(from)); - EventList* el = wp->events(); - for (iEvent e = el->begin(); e != el->end(); ++e) { - Event event = e->second; - SndFileR f = event.sndFile(); - if (f.isNull()) - continue; - unsigned channels = f.channels(); - if (channels == 0) { - printf("drawWavePart: channels==0! %s\n", f.finfo()->fileName().toLatin1().data()); - continue; - } - - int x1 = pos2pix(event.pos() + *wp); - int x2 = pos2pix(event.end() + *wp); - int w = x2 - x1; - if (w == 0) - continue; - - int samples = event.lenFrame(); - int xScale = (samples + w/2)/w; - int frame = pos.frame() - wp->frame() - - event.pos().frame() + event.spos(); - - if (h < 20) { - // - // combine multi channels into one waveform - // - for (int i = from; i < to; i++) { - SampleV sa[channels]; - f.read(sa, xScale, frame); - frame += xScale; - int peak = 0; - int rms = 0; - for (unsigned k = 0; k < channels; ++k) { - if (sa[k].peak > peak) - peak = sa[k].peak; - rms += sa[k].rms; - } - rms /= channels; - peak = (peak * (th-2)) >> 9; - rms = (rms * (th-2)) >> 9; - p.setPen(QColor(Qt::darkGray)); - p.drawLine(i, y - peak - cc, i, y + peak); - p.setPen(QColor(Qt::black)); - p.drawLine(i, y - rms - cc, i, y + rms); - } - } - else { - // - // multi channel display - // - h = th / (channels * 2); - int cc = th % (channels * 2) ? 0 : 1; - for (int i = from; i < to; i++) { - y = y0 + 1 + h; - SampleV sa[channels]; - f.read(sa, xScale, frame); - frame += xScale; - for (unsigned k = 0; k < channels; ++k) { - // peak = (sa[k].peak * h) / 256; - int peak = (sa[k].peak * (h - 1)) >> 8; - int rms = (sa[k].rms * (h - 1)) >> 8; - p.setPen(QColor(Qt::darkGray)); - p.drawLine(i, y - peak - cc, i, y + peak); - p.setPen(QColor(Qt::black)); - p.drawLine(i, y - rms - cc, i, y + rms); - y += 2 * h; - } - } - } - } - } - -//--------------------------------------------------------- -// paint -//--------------------------------------------------------- - -void PartCanvas::paint(QPainter& p, QRect r) - { - //printf("canvas paint %d %d %d %d\n", r.x(), r.y(), r.width(), r.height()); - QFont f = font(); - f.setPointSize(8); - p.setFont(f); - - int from = r.x(); - int to = from + r.width(); - - TrackList* tl = song->tracks(); - ArrangerTrack* at = 0; - for (iTrack i = tl->begin(); i != tl->end(); ++i) { - Track* t = *i; - at = &(t->arrangerTrack); - if (at->tw == 0) - continue; - - int y = at->tw->y(); // - splitWidth/2; - int h = at->tw->height() - 1; - - PartList* pl = t->parts(); - for (iPart ip = pl->begin(); ip != pl->end(); ++ip) { - Part* part = ip->second; - int x1 = pos2pix(*part); - int x2 = pos2pix(part->end()); - int len = x2 - x1; - - if (x2 <= from) - continue; - if (x1 > to) - break; - - QRect pr(x1, y, len, h - partBorderWidth); - bool clone = part->isClone(); - - QPen pen(QColor(100, 100, 100), partBorderWidth, clone ? Qt::DashLine : Qt::SolidLine); - QBrush brush(Qt::SolidPattern); - QLinearGradient lg(0, pr.y() - wpos.y()-r.y(), - 0, pr.y()+ 2*pr.height() -wpos.y()-r.y()); - lg.setColorAt(0, part->selected()?Qt::gray - :config.partColors[part->colorIndex()]); - lg.setColorAt(1, Qt::white); - QBrush brushLG(lg); - if (part->selected()) { - pen.setColor(config.partColors[part->colorIndex()]); - brush.setColor(config.selectPartBg); - p.setBrush(brushLG); - } - else if (part->mute()) { - pen.setColor(Qt::red); - brush.setColor(Qt::gray); - p.setBrush(brush); - } - else { - //brush.setColor(config.partColors[part->colorIndex()]); - p.setBrush(brushLG); - } - p.setPen(pen); - // - // we want to draw the rectangle without transformation - // to get equal border width horizontal and vertical - // - QRect rr(p.matrix().mapRect(pr).adjusted(1, 0, -1, 0)); - p.save(); - p.resetMatrix(); - p.drawRect(rr); - p.restore(); - - int xx1 = x1; - if (xx1 < from) - xx1 = from; - int xx2 = x2; - if (xx2 > to) - xx2 = to; - if (t->isMidiTrack()) - drawMidiPart(p, part, y, h, xx1, xx2); - else if (t->type() == Track::WAVE) - drawWavePart(p, part, y, h, xx1, xx2); - int yy = y + h - partLabelHeight; - p.drawText(x1 + 3, yy, len - 6, - partLabelHeight-1, Qt::AlignVCenter | Qt::AlignLeft, - part->name()); - - // redraw border - p.save(); - p.resetMatrix(); - p.setPen(pen); - p.setBrush(Qt::NoBrush); - p.drawRect(rr); - p.restore(); - } - - if (i != tl->begin()) { - p.setPen(QPen(Qt::lightGray, trackSeparator, Qt::SolidLine)); - p.drawLine(from, y + yTrackOffset, to, y + yTrackOffset); - } - for (iArrangerTrack i = t->subtracks.begin(); i != t->subtracks.end(); ++i) { - at = *i; - if (at->tw == 0) - continue; - TLSWidget* tls = (TLSWidget*)(at->tw); - int y = tls->y(); - // int h = tls->height(); - p.setPen(QPen(Qt::lightGray, trackSeparator, Qt::SolidLine)); - p.drawLine(from, y + yTrackOffset, to, y + yTrackOffset); - y += yTrackOffset + trackSeparator; - QPoint off(0, y); - p.translate(off); - // tls->paint(p, r); - tls->paint(p, QRect(from, 0, to-from, tls->height() - (yTrackOffset + trackSeparator))); - p.translate(-off); - } - } - if (at && at->tw) { - // draw last line - int y = at->tw->y() + at->tw->height() + yTrackOffset; - p.setPen(QPen(Qt::lightGray, trackSeparator, Qt::SolidLine)); - p.drawLine(from, y, to, y); - } - if (state == S_DRAG4 || state == S_DRAG1 || state == S_DRAG2 || state == S_DRAG5) { - p.setBrush(Qt::NoBrush); - p.setPen(QPen(QColor(Qt::red), partBorderWidth)); - p.drawRect(drag); - } - } - -//--------------------------------------------------------- -// drawMidiPart -//--------------------------------------------------------- - -void PartCanvas::drawMidiPart(QPainter& p, Part* mp, int y, int th, int from, int to) - { - p.setPen(Qt::black); - - EventList* events = mp->events(); - // iEvent ito(events->lower_bound(to)); - - iEvent ito = events->end(); -// int pos = pos2pix(*mp); - - if (config.canvasShowPartType & 2) { // show events - for (iEvent i = events->lower_bound(from); i != ito; ++i) { - EventType type = i->second.type(); - if ( - ((config.canvasShowPartEvent & 1) && (type == Note)) - || ((config.canvasShowPartEvent & 2) && (type == PAfter)) - || ((config.canvasShowPartEvent & 4) && (type == Controller)) - || ((config.canvasShowPartEvent &16) && (type == CAfter)) - || ((config.canvasShowPartEvent &64) && (type == Sysex || type == Meta)) - ) { - int t = pos2pix(*mp + i->second.pos()); - p.drawLine(t, y + 1, t, y + th - 2); - } - } - } - - else { // show Cakewalk Style - for (iEvent i = events->begin(); i != ito; ++i) { - if (i->second.type() != Note) - continue; - int x1 = pos2pix(*mp + i->second.pos()); - int x2 = pos2pix(*mp + i->second.end()); - - if (x1 > to) - break; - if (x2 < from) - continue; - - if (x2 > to) // clip to drawing area - x2 = to; - if (x1 < from) - x1 = from; - int pitch = i->second.pitch(); - int yy = y + th - (pitch * th / 127); - p.drawLine(x1, yy, x2, yy); - } - } - } - -//--------------------------------------------------------- -// searchPart -//--------------------------------------------------------- - -int PartCanvas::searchPart(const QPoint& pp) - { - Pos tp(pix2pos(pp.x())); - QPoint p(tp.tick(), pp.y() + wpos.y()); - -// printf("searchPart %d %d\n", p.x(), p.y()); - track = 0; - part = 0; - at = 0; - int yp = p.y(); - if (yp < 0) - return HIT_NOTHING; - - TrackList* tl = song->tracks(); - iTrack i; - int y1, y2; - for (i = tl->begin(); i != tl->end(); ++i) { - track = *i; - QWidget* tw = track->arrangerTrack.tw; - if (tw == 0) { - printf(" invisible Track\n"); - continue; - } - y1 = tw->y(); - y2 = y1 + tw->height(); - if (yp >= y1 && yp < y2) { -// printf(" track <%s> %d - %d\n", track->name().toLatin1().data(), y1, y2); - break; - } - for (iArrangerTrack i = track->subtracks.begin(); i != track->subtracks.end(); ++i) { - at = *i; - if (at->tw == 0) { - printf("----empty subtrack?\n"); - break; - } - y1 = at->tw->y(); - y2 = y1 + at->tw->height(); - if (yp >= y1 && yp < y2) { - return HIT_SUBTRACK; - } - } - } - if (i == tl->end()) { - track = 0; - at = 0; - return HIT_NOTHING; - } - - unsigned x = p.x(); - PartList* pl = track->parts(); - for (iPart ip = pl->begin(); ip != pl->end(); ++ip) { - part = ip->second; - if (x >= part->tick() && x < part->endTick()) { - ppos = mapx(part->tick()); - psize = rmapx(part->lenTick()); -// printf(" part\n"); - return HIT_PART; - } - } - part = 0; - return HIT_TRACK; - } - -//--------------------------------------------------------- -// contextMenu -//--------------------------------------------------------- - -void PartCanvas::contextMenu(const QPoint& pos) - { - QMenu* pop = new QMenu(widget()); - QAction* a; - if (part) { - pop->addAction(getAction("cut", this)); - pop->addAction(getAction("copy", this)); - pop->addSeparator(); - a = pop->addAction(tr("Rename")); - a->setData("rename"); - - QMenu* cp = pop->addMenu(tr("Color")); - - // part color selection - for (int i = 0; i < NUM_PARTCOLORS; ++i) { - a = cp->addAction(partColorNames[i]); - a->setData(QString("color%1").arg(i)); - QPixmap pm(20, 20); - QPainter p(&pm); - p.fillRect(0, 0, 20, 20, config.partColors[i]); - a->setIcon(QIcon(pm)); - } - pop->addAction(getAction("delete", this)); - pop->addAction(getAction("scissor", this)); - pop->addAction(getAction("glue", this)); - a = getAction("declone", this); - a->setEnabled(part->isClone()); - pop->addAction(a); - if (track->type() == Track::MIDI) { - a = pop->addAction(tr("AutoFill...")); - a->setData("autofill"); - } - pop->addSeparator(); - if (track->type() == Track::MIDI) { - MidiTrack* track = (MidiTrack*)part->track(); - if (track->useDrumMap()) { - a = pop->addAction(*edit_drummsIcon, tr("drums")); - a->setData("editdrums"); - } - else { - a = pop->addAction(QIcon(":/xpm/piano.xpm"), tr("pianoroll")); - a->setData("editpiano"); - } - a = pop->addAction(*edit_listIcon, tr("miditracker")); - a->setData("miditracker"); - pop->addAction(getAction("listedit", this)); - } - else { - a = pop->addAction(*waveIcon, tr("wave edit")); - a->setData("waveedit"); - } - - a = pop->exec(mapToGlobal(pos)); - if (a) { - QString cmd = a->data().toString(); - if (cmd == "rename") - renamePart(part); - else if (cmd == "delete") - song->cmdRemovePart(part); - else if (cmd == "scissor") - splitPart(part, startDrag); - else if (cmd == "glue") - song->cmdGluePart(part); - else if (cmd == "cut") - cutPart(part); - else if (cmd == "copy") - copyPart(part); - else if (cmd == "editpiano") - emit startEditor(part, 0); - else if (cmd == "miditracker") - emit startEditor(part, 2); - else if (cmd == "listedit") - emit startEditor(part, 1); - else if (cmd == "drumedit") - emit startEditor(part, 3); - else if (cmd == "waveedit") - emit startEditor(part, 4); - else if (cmd == "declone") - declonePart(part); - else if (cmd == "autofill") { - bool ok; - int ticksM = AL::sigmap.ticksMeasure(part->tick()); - int n = QInputDialog::getInteger(this, - tr("MusE: Get auto fill loop len"), - tr("Measures: "), - part->fillLen() / ticksM, - 0, 16, 1, &ok); - if (ok) { - part->setFillLen(n * ticksM); - } - } - else if (cmd.startsWith("color")) { - int idx = cmd.mid(5).toInt(); - part->setColorIndex(idx); - widget()->update(); - } - else { - printf("unknown action <%s>\n", cmd.toLatin1().data()); - } - } - } - else { - for (int i = 0; i < TOOLS; ++i) { - if ((arrangerTools & (1 << i))==0) - continue; - a = getAction(toolList[i], this); - pop->addAction(a); - a->setCheckable(true); - a->setChecked((1 <exec(mapToGlobal(pos)); - if (a) - muse->setTool(a->data().toString()); - } - } - -//--------------------------------------------------------- -// mousePressEvent -//--------------------------------------------------------- - -void PartCanvas::mousePress(QMouseEvent* me) - { - if (state == S_SUBTRACK) { - ((TLSWidget*)(at->tw))->mouseRelease(); - state = S_NORMAL; - } - - QPoint pos(me->pos().x(), me->pos().y() - rulerHeight); - startDrag = pos; - int hit = searchPart(startDrag); - - if (hit == HIT_SUBTRACK) { - TLSWidget* w = (TLSWidget*)(at->tw); - int y = wpos.y() + pos.y() - w->y(); - w->mousePress(QPoint(pos.x(), y), me); - // propagate drag events to subtrack if left button pressed: - if (me->button() == Qt::LeftButton) - state = S_SUBTRACK; - return; - } - else if ( hit == HIT_NOTHING ) { // nothing here we put up a rubberband - rubberBandStartPos = me->pos(); - if (!rubberBand) - rubberBand = new QRubberBand(QRubberBand::Rectangle, this); - rubberBand->setGeometry(QRect(rubberBandStartPos, QSize())); - rubberBand->show(); - } - - if (button & Qt::RightButton) { - contextMenu(me->pos()); - return; - } - - QRect r1,r2; - QPoint pos2; - int xpos = 0, y = 0, len = 0, h = 0; - - if (hit == HIT_PART) { - h = track->arrangerTrack.tw->height(); - len = rmapx(part->lenTick()); - y = track->arrangerTrack.tw->y() - splitWidth/2; - xpos = mapx(part->tick()); - - r1 = QRect(xpos, y, handleWidth, h); - r2 = QRect(xpos + len - handleWidth, y, handleWidth, h); - pos2 = QPoint(pos.x(), pos.y() + wpos.y()); - } - - switch (_tool) { - case PencilTool: - if (r1.contains(pos2)) - state = S_START_DRAG1; - else if (r2.contains(pos2)) - state = S_START_DRAG2; - else - state = S_START_DRAG5; - ppos = pos2pix(pix2pos(startDrag.x()).downSnaped(raster())); - psize = pos2pix(pix2pos(ppos+1).upSnaped(raster())) - ppos; - startDragTime = QTime::currentTime(); - setCursor(); - break; - case RubberTool: - if (part) - song->cmdRemovePart(part); - break; - case GlueTool: - if (part) - song->cmdGluePart(part); - break; - case CutTool: - if (part) - splitPart(part, pos); - break; - case MuteTool: - if (part) { - part->setMute(!part->mute()); - widget()->update(); - } - break; - default: - if (hit == HIT_PART) { - QRect r3(xpos, y, len, h); - - if (r1.contains(pos2)) { - state = S_START_DRAG1; - } - else if (r2.contains(pos2)) { - state = S_START_DRAG2; - } - else if (r3.contains(pos2)) { - state = S_START_DRAG3; - bool add = keyState & Qt::ShiftModifier; - song->selectPart(part, add); - emit kbdMovementUpdate(track, part); - } - } - if (state == S_NORMAL) { - song->selectPart(0, false); // deselect all parts - emit kbdMovementUpdate(0, 0); // Tell arranger nothing is selected (Keyboard movement) - } - startDragTime = QTime::currentTime(); - setCursor(); - break; - } - } - -//--------------------------------------------------------- -// mouseMove -//--------------------------------------------------------- - -void PartCanvas::mouseMove(QPoint pos) - { - - if(rubberBand) - rubberBand->setGeometry(QRect(rubberBandStartPos, pos).normalized()); - - if (state == S_SUBTRACK) { - TLSWidget* w = (TLSWidget*)(at->tw); - int y = wpos.y() + pos.y() - w->y() - rulerHeight; - w->mouseMove(QPoint(pos.x(), y)); - return; - } - pos -= rCanvasA.topLeft(); - bool update = false; - int x = pos.x(); - int delta = startDrag.x() - x; - int t = startDragTime.msecsTo(QTime::currentTime()); - bool dragActive = (startDrag - pos).manhattanLength() > - QApplication::startDragDistance() - || t > QApplication::startDragTime(); - switch (state) { - case S_START_DRAG1: - if (dragActive) - state = S_DRAG1; - break; - case S_START_DRAG2: - if (dragActive) - state = S_DRAG2; - break; - case S_START_DRAG3: - if (dragActive) - state = S_DRAG3; - break; - case S_START_DRAG5: - if (dragActive) - state = S_DRAG5; - break; - case S_NORMAL: - { - searchPart(pos); - bool found = false; - if (part) { - int h = track->arrangerTrack.tw->height(); - int xpos = mapx(part->tick()); - int len = rmapx(part->lenTick()); - int y = track->arrangerTrack.tw->y(); - QRect r1(xpos, y, handleWidth, h); - QRect r2(xpos + len - handleWidth, y, handleWidth, h); - if (r1.contains(pos) || r2.contains(pos)) - found = true; - } - if (found) { - widget()->setCursor(Qt::SizeHorCursor); - } - else - setCursor(); - } - break; - default: - break; - } - if (!track) - return; - int y = track->arrangerTrack.tw->y(); // - splitWidth/2; - int ph = track->arrangerTrack.tw->height() - 1 - partBorderWidth; - if (state == S_DRAG1) { - // - // drag left edge of part - // - Pos p(pix2pos(ppos - delta)); - p.snap(raster()); - int x1 = pos2pix(p); - int x2 = pos2pix(part->end()); - int size = x2 - x1; - drag.setRect(x1, y, size, ph); - update = true; - } - else if (state == S_DRAG2) { - // - // drag right edge of part - // - int size = psize - delta; - if (size < 10) - size = 10; - int x2 = mapx(AL::sigmap.raster(part->tick() + rmapxDev(size), raster())); - drag.setRect(ppos, y, x2 - ppos, ph); - update = true; - } - else if (state == S_DRAG5) { - // - // draw part with pencil tool - // - int size = psize - delta; - if (size < 10) - size = 10; - int x2 = mapx(AL::sigmap.raster(mapxDev(ppos + size), raster())); - drag.setRect(ppos, y, x2 - ppos, ph); - update = true; - } - else if (state == S_DRAG3) { - // - // drag whole part - // - srcPart = part; - QDrag* d = 0; - if (track->type() == Track::MIDI) - d = new MidiPartDrag(srcPart, this); - else if (track->type() == Track::WAVE) - d = new AudioPartDrag(srcPart, this); - if (d) { - Qt::KeyboardModifiers kb = QApplication::keyboardModifiers(); - Qt::DropActions da = kb ? (Qt::MoveAction | Qt::CopyAction | Qt::LinkAction) : Qt::MoveAction; - song->startUndo(); - _dragOffset = startDrag.x() - rCanvasA.x() - ppos; - if (d->start(da) == Qt::MoveAction) - song->removePart(srcPart); - song->endUndo(0); - update = true; - } - state = S_NORMAL; - } - if (update) - widget()->update(); - } - -//--------------------------------------------------------- -// mouseRelease -//--------------------------------------------------------- - -void PartCanvas::mouseRelease(QMouseEvent* me) - { - - if (rubberBand) - rubberBand->hide(); // TODO robert, nothing more happens for the moment/ - - if (state == S_SUBTRACK) { - ((TLSWidget*)(at->tw))->mouseRelease(); - state = S_NORMAL; - return; - } - - QPoint pos(me->pos()); - int x = pos.x(); - int delta = startDrag.x() - x; - - if (state == S_DRAG1) { - int val = mapxDev(ppos-delta); - int pos = AL::sigmap.raster(val, raster()); - int size = part->tick() + part->lenTick() - pos; - emit partChanged(part, pos, size); - } - else if (state == S_DRAG2) { - int size = psize - delta; - int x1 = part->tick(); - int x2 = AL::sigmap.raster(part->tick() + rmapxDev(size), raster()); - - int step = AL::sigmap.rasterStep(x1, raster()); - if (x2 - x1 < step) - x2 = AL::sigmap.raster(x1 + step, raster()); - emit partChanged(part, x1, x2-x1); - } - else if (state == S_DRAG5) { - if (track && (track->type() == Track::MIDI || track->type() == Track::WAVE)) { - Part* part = track->newPart(); - Pos p1 = pix2pos(drag.x()).snaped(raster()); - Pos p2 = pix2pos(drag.x() + drag.width()).snaped(raster()); - part->setPos(p1); - part->setLenTick(p2.tick() - p1.tick()); - song->cmdAddPart(part); - } - else - widget()->update(); - } - state = S_NORMAL; - setCursor(); - } - -//--------------------------------------------------------- -// mouseDoubleClickEvent -//--------------------------------------------------------- - -void PartCanvas::mouseDoubleClick(QMouseEvent* me) - { - QPoint pos(me->pos().x(), me->pos().y() - rulerHeight); - if (_tool != PointerTool) { -//TD mousePress(pos); - return; - } - bool shift = keyState & Qt::ShiftModifier; - if (searchPart(pos) == HIT_PART) { - if (button == Qt::LeftButton && shift) { - renamePart(part); - } - else if (button == Qt::LeftButton) { - emit doubleClickPart(part); - } - } - // - // double click creates new part between left and - // right mark - - else if (track && track->isMidiTrack()) - emit createLRPart(track); - } - - -//--------------------------------------------------------- -// keyboardNavigate -//--------------------------------------------------------- - -void PartCanvas::keyboardNavigate(QKeyEvent *e) - { - printf("nothing here go away\n"); - } - - -//--------------------------------------------------------- -// setCursor -//--------------------------------------------------------- - -void PartCanvas::setCursor() - { - switch(state) { - case S_START_DRAG1: - case S_START_DRAG2: - case S_DRAG1: - case S_DRAG2: - widget()->setCursor(Qt::SizeHorCursor); - return; - default: - break; - } - TimeCanvas::setCursor(); - } - -//--------------------------------------------------------- -// declonePart -//--------------------------------------------------------- - -void PartCanvas::declonePart(Part* oPart) - { - Track* track = oPart->track(); - Part* nPart = track->newPart(oPart, false); - - EventList* se = oPart->events(); - for (iEvent i = se->begin(); i != se->end(); ++i) { - Event oldEvent = i->second; -// Event ev = oldEvent.clone(); - nPart->addEvent(oldEvent); - } - oPart->deref(); - song->cmdChangePart(oPart, nPart); - } - -//--------------------------------------------------------- -// splitPart -//--------------------------------------------------------- - -void PartCanvas::splitPart(Part* part, const QPoint& p) - { - song->cmdSplitPart(part, pix2pos(p.x()).snaped(raster())); - } - -//--------------------------------------------------------- -// renamePart -//--------------------------------------------------------- - -void PartCanvas::renamePart(Part* part) - { - bool ok; - - QString s = QInputDialog::getText(this, - tr("MusE: Change Part Name"), - tr("PartName:"), - QLineEdit::Normal, - part->name(), - &ok - ); - if (ok && s != part->name()) { - song->startUndo(); - Part* newPart = new Part(*part); - newPart->setName(s); - song->cmdChangePart(part, newPart); - widget()->update(); - } - } - -//--------------------------------------------------------- -// cutPart -//--------------------------------------------------------- - -void PartCanvas::cutPart(Part* part) - { - copyPart(part); - song->cmdRemovePart(part); - } - -//--------------------------------------------------------- -// copyPart -//--------------------------------------------------------- - -void PartCanvas::copyPart(Part* part) - { - QBuffer buffer; - buffer.open(QIODevice::WriteOnly); - AL::Xml xml(&buffer); - part->write(xml); - buffer.close(); - QMimeData* mimeData = new QMimeData; - mimeData->setData(MidiPartDrag::type, buffer.buffer()); - QApplication::clipboard()->setMimeData(mimeData); - } - -//--------------------------------------------------------- -// dragEnter -//--------------------------------------------------------- - -void PartCanvas::dragEnter(QDragEnterEvent* event) - { -#if 0 - QPoint p(event->pos() - rCanvasA.topLeft()); - searchPart(p); - if (!track) { - event->ignore(); - return; - } - int srcIsMidi = -1; - const QMimeData* md = event->mimeData(); - - if (MidiPartDrag::canDecode(md)) - srcIsMidi = 1; - else if (AudioPartDrag::canDecode(md)) - srcIsMidi = 0; - else if (WavUriDrag::canDecode(md)) - srcIsMidi = 0; - - int dstIsMidi = -1; - if (track->type() == Track::MIDI) - dstIsMidi = 1; - else if (track->type() == Track::WAVE) - dstIsMidi = 0; - - if ((srcIsMidi == -1) || (dstIsMidi != srcIsMidi)) { - event->ignore(); - return; - } - Qt::KeyboardModifiers kb = event->keyboardModifiers(); - if (kb == 0 && (Qt::MoveAction & event->possibleActions())) { - event->setDropAction(Qt::MoveAction); - event->accept(); - } - else -#endif - event->acceptProposedAction(); - } - -//--------------------------------------------------------- -// dragMoveEvent -//--------------------------------------------------------- - -void PartCanvas::dragMove(QDragMoveEvent* event) - { - QPoint p(event->pos() - rCanvasA.topLeft()); - searchPart(p); - if (!track) { - event->acceptProposedAction(); - return; - } - Part* srcPart = 0; - QString filename; - - bool srcIsMidi; - const QMimeData* md = event->mimeData(); - if (MidiPartDrag::canDecode(md)) { - MidiPartDrag::decode(md, srcPart); - srcIsMidi = true; - } - else if (AudioPartDrag::canDecode(md)) { - AudioPartDrag::decode(md, srcPart); - srcIsMidi = false; - } - else if (WavUriDrag::canDecode(md)) { - WavUriDrag::decode(md, &filename); - if (state != S_NORMAL) { - state = S_NORMAL; - widget()->update(); - } - if (track->type() == Track::WAVE) - event->acceptProposedAction(); - else - event->ignore(); - return; - } - else { - state = S_NORMAL; - event->ignore(); - return; - } - - int dstIsMidi = -1; - if (track->type() == Track::MIDI) - dstIsMidi = 1; - else if (track->type() == Track::WAVE) - dstIsMidi = 0; - if ((srcIsMidi == -1) || (dstIsMidi != srcIsMidi)) { - if (state != S_NORMAL) { - state = S_NORMAL; - widget()->update(); - } - event->ignore(); - return; - } - Qt::KeyboardModifiers kb = event->keyboardModifiers(); - if (kb == 0 && (Qt::MoveAction & event->possibleActions())) { - event->setDropAction(Qt::MoveAction); - event->accept(); - } - else - event->acceptProposedAction(); - state = S_DRAG4; - ArrangerTrack* at = &(track->arrangerTrack); - - PartCanvas* cw = (PartCanvas*)event->source(); - QRect updateRect(drag); - - Pos pos; - if (cw) - pos = pix2pos(p.x() - cw->dragOffset()).snaped(raster()); - else - pos = pix2pos(p.x()).snaped(raster()); - drag.setRect( - pos2pix(pos), - at->tw->y(), - rmapx(srcPart->lenTick()), - at->tw->height() - 1 - partBorderWidth - ); - delete srcPart; - updateRect |= drag; - updateRect.adjust(-1, -1 + rCanvasA.y(), 1, 1 + rCanvasA.y()); - widget()->update(updateRect); - } - -//--------------------------------------------------------- -// dropEvent -//--------------------------------------------------------- - -void PartCanvas::drop(QDropEvent* event) - { - state = S_NORMAL; - Part* dstPart = 0; - QString filename; - - QPoint pos(event->pos() - rCanvasA.topLeft()); - const QMimeData* md = event->mimeData(); - if (WavUriDrag::canDecode(md)) { - WavUriDrag::decode(md, &filename); - int tick = AL::sigmap.raster(mapxDev(pos.x()), raster()); - Pos pos(tick); - muse->importWaveToTrack(filename, track, pos); - widget()->update(); - return; - } - - bool isMidi = false; - if (MidiPartDrag::canDecode(md)) { - MidiPartDrag::decode(md, dstPart); - isMidi = true; - } - else if (AudioPartDrag::canDecode(md)) - AudioPartDrag::decode(md, dstPart); - - searchPart(pos); - if (!dstPart) - return; - PartCanvas* cw = (PartCanvas*)event->source(); - bool needEndUndo = false; - if (!track) { - if (isMidi) - track = new MidiTrack(); - else - track = new WaveTrack(); - track->setDefaultName(); - if (cw) - song->insertTrack(track, -1); - else { - song->startUndo(); - song->insertTrack(track, -1); - needEndUndo = true; - } - } - else if (isMidi != track->isMidiTrack()) - return; - - dstPart->setTrack(track); - - // - // cw == 0 means that we are dropping to - // another application - - unsigned tick; - if (cw) - tick = AL::sigmap.raster(mapxDev(pos.x() - cw->dragOffset()), raster()); - else - tick = AL::sigmap.raster(mapxDev(pos.x()), raster()); - - dstPart->setTick(tick); - - Qt::DropAction da = event->proposedAction(); - Qt::KeyboardModifiers kb = event->keyboardModifiers(); - if (kb == 0 && (Qt::MoveAction & event->possibleActions())) - da = Qt::MoveAction; - - if ((da == Qt::LinkAction) && (cw == this)) { - delete dstPart->events(); - dstPart->clone(srcPart->events()); - event->setDropAction(Qt::LinkAction); - } - else if (da == Qt::MoveAction) - event->setDropAction(Qt::MoveAction); - else - event->setDropAction(Qt::CopyAction); - event->accept(); - if (cw || needEndUndo) - song->addPart(dstPart); - else - song->cmdAddPart(dstPart); - if (needEndUndo) - song->endUndo(0); - widget()->update(); - } - -//--------------------------------------------------------- -// dragLeave -//--------------------------------------------------------- - -void PartCanvas::dragLeave(QDragLeaveEvent*) - { - if (state == S_DRAG4) { - state = S_NORMAL; - widget()->update(); - } - } - diff --git a/muse/muse/arranger/canvas.h b/muse/muse/arranger/canvas.h deleted file mode 100644 index 911936c2..00000000 --- a/muse/muse/arranger/canvas.h +++ /dev/null @@ -1,124 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#ifndef __CANVAS_H__ -#define __CANVAS_H__ - -#include "awl/tcanvas.h" -#include "widgets/tools.h" - -class CanvasWidget; -class Part; -class Track; -class ArrangerTrack; - -static const int HANDLE1 = 6; -static const int HANDLE2 = 3; - -//--------------------------------------------------------- -// PartCanvas -//--------------------------------------------------------- - -class PartCanvas : public TimeCanvas { - Q_OBJECT - - // DRAG1 drag part head - // DRAG2 drag part tail - // DRAG3 drag whole part - // DRAG4 Drag&Drop drag - // DRAG5 draw part with pencil tool - - enum { S_NORMAL, S_START_DRAG1, S_START_DRAG2, S_START_DRAG3, - S_DRAG1, S_DRAG2, S_DRAG3, - S_DRAG4, - S_START_DRAG5, S_DRAG5, // draw new Part - S_SUBTRACK - }; - int state; - QPoint startDrag; - int _dragOffset; - QRect drag; - QTime startDragTime; - unsigned ppos, psize; - - // values set by searchPart(): - Track* track; - Part* part; - ArrangerTrack* at; - - Part* srcPart; // src part of a drag/drop operation - - bool _drawBackground; - int selected; - int lselected; // in local coordinates - int starty; - int dragy; - - virtual void paint(QPainter&, QRect); - void drawWavePart(QPainter& p, Part* part, int, int, int, int); - void drawMidiPart(QPainter& p, Part* mp, int, int, int, int); - virtual void mousePress(QMouseEvent*); - virtual void mouseMove(QPoint); - virtual void mouseRelease(QMouseEvent*); - virtual void mouseDoubleClick(QMouseEvent*); - - virtual void dragEnter(QDragEnterEvent*); - virtual void drop(QDropEvent*); - virtual void dragMove(QDragMoveEvent*); - virtual void dragLeave(QDragLeaveEvent*); - - virtual void keyboardNavigate(QKeyEvent *e); - - - int searchPart(const QPoint& p); - - void declonePart(Part* part); - void renamePart(Part*); - void splitPart(Part*, const QPoint&); - void cutPart(Part*); - void copyPart(Part*); - - void setCursor(); - int dragOffset() const { return _dragOffset; } - void drawHandle(QPainter& p, int x, int y) { - p.fillRect(x-HANDLE2, y-HANDLE2, HANDLE1, HANDLE1, x == lselected ? Qt::red : Qt::yellow); - } - void contextMenu(const QPoint&); - - QRubberBand *rubberBand; - QPoint rubberBandStartPos; - - private slots: - void markerChanged(int); - - signals: - void kbdMovementUpdate(Track* t, Part* p); - void startEditor(Part*, int); - void createLRPart(Track*); - void partChanged(Part*, unsigned, unsigned); - void doubleClickPart(Part*); - - public: - PartCanvas(); - void setDrawBackground(bool val) { _drawBackground = val; } - }; - -#endif - diff --git a/muse/muse/arranger/configtrack.cpp b/muse/muse/arranger/configtrack.cpp deleted file mode 100644 index a8fee6a3..00000000 --- a/muse/muse/arranger/configtrack.cpp +++ /dev/null @@ -1,265 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#include "configtrack.h" -#include "trelement.h" -#include "arranger.h" - -//--------------------------------------------------------- -// ConfigTrackList -//--------------------------------------------------------- - -ConfigTrackList::ConfigTrackList(QWidget* parent) - : QDialog(parent) - { - setupUi(this); - // does not work: - configuredList->setSelectionMode(QAbstractItemView::SingleSelection); - availableList->setSelectionMode(QAbstractItemView::SingleSelection); - - up->setEnabled(false); - down->setEnabled(false); - addItem->setEnabled(false); - removeItem->setEnabled(false); - dirty = false; - curType = 0; - init(); - - connect(trackType, SIGNAL(activated(int)), SLOT(trackTypeChanged(int))); - connect(availableList, SIGNAL(itemSelectionChanged()), SLOT(availableSelected())); - connect(configuredList, SIGNAL(itemSelectionChanged()), SLOT(configuredSelected())); - connect(up, SIGNAL(clicked()), SLOT(upClicked())); - connect(down, SIGNAL(clicked()), SLOT(downClicked())); - connect(addItem, SIGNAL(clicked()), SLOT(addItemClicked())); - connect(removeItem, SIGNAL(clicked()), SLOT(removeItemClicked())); - } - -//--------------------------------------------------------- -// init -//--------------------------------------------------------- - -void ConfigTrackList::init() - { - trackType->clear(); - for (int tt = 0; tt < Track::TRACK_TYPES; ++tt) { - list[tt] = glist[tt]; - trackType->addItem(Track::_clname[tt]); - } - trackTypeChanged(curType); - } - -//--------------------------------------------------------- -// done -//--------------------------------------------------------- - -void ConfigTrackList::done(int code) - { - if (code) { - // OK pressed - if (dirty) - saveTrackType(); - for (int tt = 0; tt < Track::TRACK_TYPES; ++tt) - glist[tt] = list[tt]; - emit trackConfigChanged(); - } - else { - dirty = false; - init(); - } - QDialog::done(code); - } - -//--------------------------------------------------------- -// saveTrackType -//--------------------------------------------------------- - -void ConfigTrackList::saveTrackType() - { - dirty = false; - list[curType].clear(); - int gn = 0; - TrElementList group; - int n = configuredList->count(); - for (int i = 0; i < n; ++i) { - QString s = configuredList->item(i)->text(); - int k; - for (k = 0; k < nTrElements; ++k) - if (trElements[k].name == s) - break; - if (trElements[k].grp != gn) { - list[curType].push_back(group); - group.clear(); - gn = trElements[k].grp; - } - group.push_back(&trElements[k]); - } - if (!group.empty()) - list[curType].push_back(group); - } - -//--------------------------------------------------------- -// trackTypeChanged -//--------------------------------------------------------- - -void ConfigTrackList::trackTypeChanged(int type) - { - curType = type; - if (dirty) - saveTrackType(); - - configuredList->clear(); - TrGroupList& gl = list[type]; - for (iTrGroup i = gl.begin(); i != gl.end(); ++i) { - for (iTrElement k = i->begin(); k != i->end(); ++k) - configuredList->addItem((*k)->name); - } - - availableList->clear(); - for (int i = 0; i < nTrElements; ++i) { - QString name(trElements[i].name); - bool f = false; - - // is gui element available for this track type? - - for (int i = 0; i < nTrElements; ++i) { - const TrElement& el = trElements[i]; - if (el.name == name) { - if (el.trackMask & (1 << type)) { - f = true; - break; - } - } - } - if (!f) - continue; - - // is gui element already configured? - - for (iTrGroup i = gl.begin(); i != gl.end(); ++i) { - for (iTrElement k = i->begin(); k != i->end(); ++k) { - if (name == (*k)->name) { - f = false; - break; - } - } - if (!f) - break; - } - if (f) { - availableList->addItem(name); - } - } - } - -//--------------------------------------------------------- -// configuredSelected -//--------------------------------------------------------- - -void ConfigTrackList::configuredSelected() - { - QListWidgetItem* item = configuredList->selectedItems().at(0); - up->setEnabled(item != 0); - down->setEnabled(item != 0); - removeItem->setEnabled(item != 0); - } - -//--------------------------------------------------------- -// availableSelected -//--------------------------------------------------------- - -void ConfigTrackList::availableSelected() - { - QListWidgetItem* item = availableList->selectedItems().at(0); - addItem->setEnabled(item != 0); - } - -//--------------------------------------------------------- -// upClicked -//--------------------------------------------------------- - -void ConfigTrackList::upClicked() - { - QListWidgetItem* item = configuredList->selectedItems().at(0); - int n = configuredList->row(item); - if (n <= 0) - return; - QString s = item->text(); - delete item; - configuredList->insertItem(n-1, s); - configuredList->setItemSelected(configuredList->item(n-1), true); - dirty = true; - } - -//--------------------------------------------------------- -// downClicked -//--------------------------------------------------------- - -void ConfigTrackList::downClicked() - { - QListWidgetItem* item = configuredList->selectedItems().at(0); - int n = configuredList->row(item); - if (n >= int(configuredList->count()-1)) - return; - QString s = item->text(); - - delete item; - configuredList->insertItem(n+1, s); - configuredList->setItemSelected(configuredList->item(n+1), true); - dirty = true; - } - -//--------------------------------------------------------- -// addItemClicked -//--------------------------------------------------------- - -void ConfigTrackList::addItemClicked() - { - QListWidgetItem* item = availableList->selectedItems().at(0); - if (item == 0) - return; - QString s = item->text(); - delete item; - configuredList->addItem(s); - configuredList->setItemSelected(configuredList->item(configuredList->count()-1), true); - QListWidgetItem* ci = availableList->currentItem(); - if (ci) - availableList->setItemSelected(ci, true); - dirty = true; - } - -//--------------------------------------------------------- -// removeItemClicked -//--------------------------------------------------------- - -void ConfigTrackList::removeItemClicked() - { - QListWidgetItem* item = configuredList->selectedItems().at(0); - if (item == 0) - return; - QString s = item->text(); - delete item; - availableList->addItem(s); - availableList->setItemSelected(availableList->item(availableList->count()-1), true); - QListWidgetItem* ci = configuredList->item(configuredList->currentRow()); - if (ci) - configuredList->setItemSelected(ci, true); - dirty = true; - } - diff --git a/muse/muse/arranger/configtrack.h b/muse/muse/arranger/configtrack.h deleted file mode 100644 index 47dd0f4a..00000000 --- a/muse/muse/arranger/configtrack.h +++ /dev/null @@ -1,61 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#ifndef __CONFIG_TRACK_H__ -#define __CONFIG_TRACK_H__ - -#include "ui_configtrack.h" -#include "track.h" -#include "trelement.h" - -struct TrElement; -class TrGroupList; - -//--------------------------------------------------------- -// ConfigTrackList -//--------------------------------------------------------- - -class ConfigTrackList : public QDialog, Ui::ConfigTrackListBase { - Q_OBJECT - - TrGroupList list[Track::TRACK_TYPES]; - void init(); - bool dirty; - void saveTrackType(); - int curType; - - private slots: - void trackTypeChanged(int); - void availableSelected(); - void configuredSelected(); - void upClicked(); - void downClicked(); - void addItemClicked(); - void removeItemClicked(); - virtual void done(int); - - signals: - void trackConfigChanged(); - - public: - ConfigTrackList(QWidget*); - }; - -#endif diff --git a/muse/muse/arranger/configtrack.ui b/muse/muse/arranger/configtrack.ui deleted file mode 100644 index 350b405a..00000000 --- a/muse/muse/arranger/configtrack.ui +++ /dev/null @@ -1,299 +0,0 @@ - - - - - ConfigTrackListBase - - - - 0 - 0 - 545 - 352 - - - - MusE: Config Track List - - - true - - - - 11 - - - 6 - - - - - 0 - - - 6 - - - - - Track Type: - - - - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - - - - - - 0 - - - 6 - - - - - 0 - - - 6 - - - - - Available Items: - - - - - - - QAbstractItemView::SelectRows - - - 0 - - - - - - - - - 0 - - - 6 - - - - - Add - - - - - - - Remove - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 40 - - - - - - - - Up - - - - - - - Down - - - - - - - - - 0 - - - 6 - - - - - Configured Items - - - - - - - QAbstractItemView::SelectRows - - - - - - - - - - - 0 - - - 6 - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - - - - - - 0 - - - 6 - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 20 - 20 - - - - - - - - &OK - - - - - - true - - - true - - - - - - - &Cancel - - - - - - true - - - - - - - - - qPixmapFromMimeSource - - - - ok - clicked() - ConfigTrackListBase - accept() - - - 393 - 321 - - - 259 - 326 - - - - - cancel - clicked() - ConfigTrackListBase - reject() - - - 484 - 327 - - - 437 - 283 - - - - - diff --git a/muse/muse/arranger/midiportinfo.ui b/muse/muse/arranger/midiportinfo.ui deleted file mode 100644 index ad8ae201..00000000 --- a/muse/muse/arranger/midiportinfo.ui +++ /dev/null @@ -1,92 +0,0 @@ - - MidiPortInfoBase - - - - 0 - 0 - 142 - 96 - - - - - 0 - 0 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 16777215 - 24 - - - - Midi Instrument - - - - - - - - 16777215 - 24 - - - - 127 - - - 127 - - - - - - - - 16777215 - 24 - - - - Device-Id: - - - - - - - - diff --git a/muse/muse/arranger/miditrackinfo.ui b/muse/muse/arranger/miditrackinfo.ui deleted file mode 100644 index c1624188..00000000 --- a/muse/muse/arranger/miditrackinfo.ui +++ /dev/null @@ -1,292 +0,0 @@ - - MidiTrackInfoBase - - - - 0 - 0 - 135 - 165 - - - - - 0 - 0 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 16777215 - 24 - - - - Transp. - - - - - - - - 0 - 0 - - - - - 16777215 - 24 - - - - Pitch Transpose - - - -127 - - - 127 - - - - - - - - 0 - 0 - - - - - 16777215 - 24 - - - - Delay - - - - - - - - 0 - 0 - - - - - 16777215 - 24 - - - - Track Delay (ticks) - - - -1000 - - - 1000 - - - - - - - - 0 - 0 - - - - - 16777215 - 24 - - - - Length - - - - - - - - 0 - 0 - - - - - 16777215 - 24 - - - - Modify Note Length - - - % - - - 25 - - - 200 - - - - - - - - 0 - 0 - - - - - 16777215 - 24 - - - - Velocity - - - - - - - - 0 - 0 - - - - - 16777215 - 24 - - - - Modify Note Velocity - - - -127 - - - 127 - - - - - - - - 0 - 0 - - - - - 16777215 - 24 - - - - Compr. - - - - - - - - 0 - 0 - - - - - 16777215 - 24 - - - - Compress Note Velocity - - - % - - - 25 - - - 200 - - - - - - - - 0 - 0 - - - - - 16777215 - 24 - - - - Instrument Patch - - - ??? - - - - - - - - diff --git a/muse/muse/arranger/partdrag.cpp b/muse/muse/arranger/partdrag.cpp deleted file mode 100644 index c47d3c11..00000000 --- a/muse/muse/arranger/partdrag.cpp +++ /dev/null @@ -1,199 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#include "partdrag.h" -#include "al/xml.h" -#include "part.h" - -const char MidiPartDrag::type[] = "application/muse/part/midi"; -const char AudioPartDrag::type[] = "application/muse/part/audio"; -const char WavUriDrag::type[] = "text/uri-list"; - -//--------------------------------------------------------- -// MidiPartDrag -//--------------------------------------------------------- - -MidiPartDrag::MidiPartDrag(Part* part, QWidget* src) - : QDrag(src) - { - QBuffer buffer; - buffer.open(QIODevice::WriteOnly); - AL::Xml xml(&buffer); - part->write(xml); - buffer.close(); - QMimeData* mimeData = new QMimeData; - mimeData->setData(type, buffer.buffer()); - setMimeData(mimeData); - } - -//--------------------------------------------------------- -// canDecode -//--------------------------------------------------------- - -bool MidiPartDrag::canDecode(const QMimeData* s) - { - return s->hasFormat(type); - } - -//--------------------------------------------------------- -// decode -//--------------------------------------------------------- - -bool MidiPartDrag::decode(const QMimeData* s, Part*& p) - { - p = 0; - QDomDocument doc; - int line, column; - QString err; - if (!doc.setContent(s->data(type), false, &err, &line, &column)) { - QString col, ln, error; - col.setNum(column); - ln.setNum(line); - error = err + "\n at line: " + ln + " col: " + col; - printf("error parsing part: %s\n", error.toLatin1().data()); - return false; - } - for (QDomNode node = doc.documentElement(); !node.isNull(); node = node.nextSibling()) { - QDomElement e = node.toElement(); - if (e.isNull()) - continue; - if (e.tagName() == "part") { - p = new Part(0); - p->ref(); - p->read(node, true); - } - else - printf("MusE: %s not supported\n", e.tagName().toLatin1().data()); - } - return (p != 0); - } - -//--------------------------------------------------------- -// PartDrag -// does only transfer reference to part, this does -// not allow for transfers between different apps -// TODO: transfer content (xml representation) -//--------------------------------------------------------- - -AudioPartDrag::AudioPartDrag(Part* part, QWidget* src) - : QDrag(src) - { - QBuffer buffer; - buffer.open(QIODevice::WriteOnly); - Xml xml(&buffer); - part->write(xml); - buffer.close(); - - QMimeData* mimeData = new QMimeData; - mimeData->setData(type, buffer.buffer()); - setMimeData(mimeData); - } - -//--------------------------------------------------------- -// canDecode -//--------------------------------------------------------- - -bool AudioPartDrag::canDecode(const QMimeData* s) - { - return s->hasFormat(type); - } - -//--------------------------------------------------------- -// decode -//--------------------------------------------------------- - -bool AudioPartDrag::decode(const QMimeData* s, Part*& p) - { - p = 0; - QDomDocument doc; - int line, column; - QString err; - if (!doc.setContent(s->data(type), false, &err, &line, &column)) { - QString col, ln, error; - col.setNum(column); - ln.setNum(line); - error = err + "\n at line: " + ln + " col: " + col; - printf("error parsing part: %s\n", error.toLatin1().data()); - return false; - } - for (QDomNode node = doc.documentElement(); !node.isNull(); node = node.nextSibling()) { - QDomElement e = node.toElement(); - if (e.isNull()) - continue; - if (e.tagName() == "part") { - p = new Part(0); - p->ref(); - p->read(node, false); - } - else - printf("MusE: %s not supported\n", e.tagName().toLatin1().data()); - } - return (p != 0); - } - -//--------------------------------------------------------- -// WavUriDrag -//--------------------------------------------------------- - -WavUriDrag::WavUriDrag(const QString& s, QWidget* src) - : QDrag(src) - { - QByteArray a(s.toAscii()); - QMimeData* mimeData = new QMimeData; - mimeData->setData(type, a); - setMimeData(mimeData); - } - -//--------------------------------------------------------- -// canDecode -//--------------------------------------------------------- - -bool WavUriDrag::canDecode(const QMimeData* s) - { - if (!s->hasFormat(type)) - return false; - QByteArray data = s->data(type); - QUrl url(data); - if (url.scheme() != "file") - return false; - QFileInfo fi(url.toLocalFile().trimmed()); - if (!fi.exists()) { - printf("drag file <%s> does not exist\n", fi.filePath().toLatin1().data()); - return false; - } - if (fi.suffix() != "wav") { - printf("drag file <%s> has no wav suffix\n", fi.filePath().toLatin1().data()); - return false; - } - return true; - } - -//--------------------------------------------------------- -// decode -//--------------------------------------------------------- - -bool WavUriDrag::decode(const QMimeData* s, QString* uri) - { - QByteArray data = s->data(type); - QUrl url(data); - *uri = url.toLocalFile().trimmed(); - return true; - } - diff --git a/muse/muse/arranger/partdrag.h b/muse/muse/arranger/partdrag.h deleted file mode 100644 index d8c2e978..00000000 --- a/muse/muse/arranger/partdrag.h +++ /dev/null @@ -1,69 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#ifndef __PARTDRAG_H__ -#define __PARTDRAG_H__ - -class Part; - -//--------------------------------------------------------- -// MidiPartDrag -//--------------------------------------------------------- - -class MidiPartDrag : public QDrag { - Q_OBJECT - - public: - static const char type[]; - MidiPartDrag(Part*, QWidget* src); - static bool canDecode(const QMimeData*); - static bool decode(const QMimeData* s, Part*& p); - }; - -//--------------------------------------------------------- -// AudioPartDrag -//--------------------------------------------------------- - -class AudioPartDrag : public QDrag { - Q_OBJECT - - public: - static const char type[]; - AudioPartDrag(Part*, QWidget* src); - static bool canDecode(const QMimeData*); - static bool decode(const QMimeData* s, Part*& p); - }; - -//--------------------------------------------------------- -// WavUriDrag -//--------------------------------------------------------- - -class WavUriDrag : public QDrag { - Q_OBJECT - - public: - static const char type[]; - WavUriDrag(const QString&, QWidget* src); - static bool canDecode(const QMimeData*); - static bool decode(const QMimeData* s, QString* p); - }; - -#endif - diff --git a/muse/muse/arranger/selectfilter.h b/muse/muse/arranger/selectfilter.h deleted file mode 100644 index a28e6947..00000000 --- a/muse/muse/arranger/selectfilter.h +++ /dev/null @@ -1,51 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#ifndef __SELECTFILTER_H__ -#define __SELECTFILTER_H__ - -//--------------------------------------------------------- -// SelectFilter -//--------------------------------------------------------- - -class SelectFilter :public QObject - { - QWidget* w; - Track* t; - - protected: - bool eventFilter(QObject*, QEvent* ev) - { - if (ev->type() == QEvent::MouseButtonPress) { - w->setFocus(); - song->selectTrack(t); - } - return false; - } - public: - SelectFilter(QObject* parent, QWidget* widget, Track* track) - : QObject(parent) { - w = widget; - t = track; - } - }; - -#endif - diff --git a/muse/muse/arranger/tllineedit.cpp b/muse/muse/arranger/tllineedit.cpp deleted file mode 100644 index 0581b858..00000000 --- a/muse/muse/arranger/tllineedit.cpp +++ /dev/null @@ -1,70 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#include "tllineedit.h" - -//--------------------------------------------------------- -// TLLineEdit -//--------------------------------------------------------- - -TLLineEdit::TLLineEdit(const QString& contents, QWidget* parent) - : QLineEdit(contents, parent) - { - setReadOnly(true); - setFrame(false); - setAlignment(Qt::AlignLeft); - setCursorPosition(0); - connect(this, SIGNAL(editingFinished()), SLOT(contentHasChanged())); - } - -//--------------------------------------------------------- -// contentHasChanged -//--------------------------------------------------------- - -void TLLineEdit::contentHasChanged() - { - setReadOnly(true); - setFrame(false); - if (isModified()) - emit contentChanged(text()); - setModified(false); - } - -//--------------------------------------------------------- -// mouseDoubleClickEvent -//--------------------------------------------------------- - -void TLLineEdit::mouseDoubleClickEvent(QMouseEvent*) - { - setReadOnly(false); - setFocus(); - setFrame(true); - } - -//--------------------------------------------------------- -// mousePressEvent -//--------------------------------------------------------- - -void TLLineEdit::mousePressEvent(QMouseEvent* ev) - { - QLineEdit::mousePressEvent(ev); - emit mousePress(); - } - diff --git a/muse/muse/arranger/tllineedit.h b/muse/muse/arranger/tllineedit.h deleted file mode 100644 index 56bfdd55..00000000 --- a/muse/muse/arranger/tllineedit.h +++ /dev/null @@ -1,48 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#ifndef __TLLINEEDIT_H__ -#define __TLLINEEDIT_H__ - -//--------------------------------------------------------- -// TLLineEdit -//--------------------------------------------------------- - -class TLLineEdit : public QLineEdit { - Q_OBJECT - - virtual void mouseDoubleClickEvent(QMouseEvent*); - virtual void mousePressEvent(QMouseEvent*); - - private slots: - void contentHasChanged(); - - signals: - void contentChanged(QString s); - void mousePress(); - - public: - TLLineEdit(const QString& contents, QWidget* parent = 0); - }; - -#endif - - - diff --git a/muse/muse/arranger/tlswidget.cpp b/muse/muse/arranger/tlswidget.cpp deleted file mode 100644 index 23b7fbc1..00000000 --- a/muse/muse/arranger/tlswidget.cpp +++ /dev/null @@ -1,355 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#include "song.h" -#include "track.h" -#include "tlswidget.h" -#include "tlwlayout.h" -#include "icons.h" -#include "arranger.h" -#include "widgets/simplebutton.h" -#include "muse.h" -#include "ctrl/configmidictrl.h" -#include "ctrl/ctrldialog.h" -#include "midictrl.h" -#include "widgets/utils.h" - -//--------------------------------------------------------- -// TLSLayout -//--------------------------------------------------------- - -class TLSLayout : public QLayout { - QList itemList; - - public: - TLSLayout() {} - ~TLSLayout(); - - void addItem(QLayoutItem* item); - void insertWidget(int index, QWidget* item); - Qt::Orientations expandingDirections() const { return 0; } - bool hasHeightForWidth() const { return false; } - int count() const { return itemList.size(); } - void setGeometry(const QRect &rect); - QSize sizeHint() const { return ((QWidget*)parent())->size(); } - QLayoutItem *itemAt(int index) const { return itemList.value(index); } - QLayoutItem *takeAt(int idx) { - return idx >= 0 && idx < itemList.size() ? itemList.takeAt(idx) : 0; - } - }; - -//--------------------------------------------------------- -// TLSLayout -//--------------------------------------------------------- - -TLSLayout::~TLSLayout() - { - QLayoutItem* child; - while ((child = takeAt(0)) != 0) - delete child; - } - -//--------------------------------------------------------- -// insertWidget -//--------------------------------------------------------- - -void TLSLayout::insertWidget(int index, QWidget* item) - { - if (item->parent() == 0) - item->setParent((QWidget*)parent()); - itemList.insert(index, new QWidgetItem(item)); - update(); - } - -//--------------------------------------------------------- -// addItem -//--------------------------------------------------------- - -void TLSLayout::addItem(QLayoutItem* item) - { - itemList.append(item); - update(); - } - -//--------------------------------------------------------- -// setGeometry -//--------------------------------------------------------- - -void TLSLayout::setGeometry(const QRect& rect) - { - static const int labelWidth = 50; - int x1 = rect.x() + labelWidth; - int y = rect.y(); - int y2 = y + rect.height(); - - QLayoutItem *item = itemList.at(0); - QSize size(item->sizeHint()); - item->widget()->setGeometry(QRect(x1 - 18, y2 - 18-splitWidth, 18, 18)); - - item = itemList.at(1); - size = item->sizeHint(); - item->setGeometry(QRect(x1, rect.y(), - rect.width() - x1 - 2, trackRowHeight)); - } - -//--------------------------------------------------------- -// TLSWidget -//--------------------------------------------------------- - -TLSWidget::TLSWidget(Track* t, ArrangerTrack* atrack, TimeCanvas* timeC) - { - setAttribute(Qt::WA_NoBackground); - setAttribute(Qt::WA_StaticContents); - setAutoFillBackground(true); - - setMouseTracking(true); - _tc = timeC; - state = S_NORMAL; - - at = atrack; - _track = t; - _ctrlTrack = t; - - TLSLayout* l = new TLSLayout; - setLayout(l); - // - // track type - // - SimpleButton* minus = newMinusButton(); - minus->setToolTip(tr("Remove Subtrack")); - l->addWidget(minus); - - ctrlList = new QToolButton; - ctrlList->setText(tr("Ctrl")); - - connect(ctrlList, SIGNAL(clicked()), SLOT(showControllerList())); - - l->addWidget(ctrlList); - ctrlList->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); - - connect(_track, SIGNAL(selectionChanged(bool)), SLOT(selectionChanged())); - connect(_track, SIGNAL(controllerChanged(int)), SLOT(controllerListChanged(int))); - connect(_track, SIGNAL(autoReadChanged(bool)), SLOT(autoReadChanged())); - connect(muse, SIGNAL(configChanged()), SLOT(configChanged())); - connect(minus, SIGNAL(clicked()), SLOT(labelMinusClicked())); - configChanged(); - } - -//--------------------------------------------------------- -// ctrl -//--------------------------------------------------------- - -Ctrl* TLSWidget::ctrl() const - { - return at->controller; - } - -//--------------------------------------------------------- -// height -//--------------------------------------------------------- - -int TLSWidget::cheight() const - { - return at->tw->height() - splitWidth; - } - -//--------------------------------------------------------- -// selectionChanged -//--------------------------------------------------------- - -void TLSWidget::selectionChanged() - { -// setFrameShadow(_track->selected() ? QFrame::Sunken : QFrame::Raised); - } - -//--------------------------------------------------------- -// configChanged -//--------------------------------------------------------- - -void TLSWidget::configChanged() - { - QColor c(_track->ccolor()); - QPalette p(palette()); - p.setColor(QPalette::Background, c.light(100)); - setPalette(p); - } - -//--------------------------------------------------------- -// showControllerList -//--------------------------------------------------------- - -bool TLSWidget::showControllerList() - { - Ctrl* c = ctrl(); - int id; - if (c) - id = c->id(); - else - id = CTRL_NO_CTRL; - for (;;) { - CtrlDialog cd(_ctrlTrack, id); - int rv = cd.exec(); - if (rv != 1) - return false; - id = cd.curId(); - if (id == CTRL_NO_CTRL) - return false; - if (id != CTRL_OTHER) - break; - ConfigMidiCtrl* mce = new ConfigMidiCtrl((MidiTrack*)_track); - mce->exec(); - delete mce; - } - setCtrl(id); - return true; - } - -//--------------------------------------------------------- -// setCtrl -//--------------------------------------------------------- - -bool TLSWidget::setCtrl(int ctrl) - { - if (ctrl == CTRL_NO_CTRL || ctrl == CTRL_OTHER) { - // this controller subtrack is new, ask user for - // controller: - return showControllerList(); - } - - if (_ctrlTrack && _ctrlTrack != _track) { - disconnect(_ctrlTrack, SIGNAL(controllerChanged(int)), this, SLOT(controllerListChanged(int))); - } - if (ctrl == CTRL_VELOCITY) { - at->controller = &veloList; - at->ctrl = CTRL_VELOCITY; - ctrlList->setText(tr("Velocity")); - _ctrlTrack = _track; - emit controllerChanged(at->ctrl); - } - else { - at->ctrl = ctrl; - at->controller = _track->getController(ctrl); - if (at->controller) { - _ctrlTrack = _track; - ctrlList->setText(at->controller->name()); - emit controllerChanged(ctrl); - } - } - return true; - } - -//--------------------------------------------------------- -// labelMinusClicked -//--------------------------------------------------------- - -void TLSWidget::labelMinusClicked() - { - emit minusClicked(this); - } - -//--------------------------------------------------------- -// mousePressEvent -//--------------------------------------------------------- - -void TLSWidget::mousePressEvent(QMouseEvent* ev) - { - if (ev->button() == Qt::RightButton) { - QMenu* menu = new QMenu(this); - QAction* a = menu->addAction(tr("Delete Controller")); - a->setData(0); - QAction* rv = menu->exec(ev->globalPos()); - if (rv == 0) - return; - emit minusClicked(this); - return; - } - song->selectTrack(_track); - - int y = ev->pos().y(); - int wh = height(); - starty = ev->globalPos().y(); - if (y > (wh - splitWidth)) { - state = S_DRAGBOTTOM; - emit startDrag(trackIdx); - } - } - -//--------------------------------------------------------- -// mouseReleaseEvent -//--------------------------------------------------------- - -void TLSWidget::mouseReleaseEvent(QMouseEvent*) - { - state = S_NORMAL; - } - -//--------------------------------------------------------- -// mouseMoveEvent -//--------------------------------------------------------- - -void TLSWidget::mouseMoveEvent(QMouseEvent* ev) - { - QPoint pos(ev->pos()); - - if (state == S_DRAGTOP) - emit drag(trackIdx-1, ev->globalPos().y() - starty); - else if (state == S_DRAGBOTTOM) - emit drag(trackIdx, ev->globalPos().y() - starty); - else { - int y = pos.y(); - int wh = height(); - if (y > (wh - splitWidth)) - setCursor(Qt::SizeVerCursor); - else - setCursor(Qt::ArrowCursor); - } - } - -//--------------------------------------------------------- -// controllerListChanged -// controller list for controller id changed -//--------------------------------------------------------- - -void TLSWidget::controllerListChanged(int id) - { - if (ctrl()->id() == id) - tc()->widget()->update(); - } - -//--------------------------------------------------------- -// autoReadChanged -//--------------------------------------------------------- - -void TLSWidget::autoReadChanged() - { - tc()->widget()->update(); - } - -//--------------------------------------------------------- -// paintEvent -//--------------------------------------------------------- - -void TLSWidget::paintEvent(QPaintEvent* ev) - { - QPainter p(this); - QRect r(ev->rect()); - p.fillRect(r, _track->ccolor()); - paintHLine(p, r.x(), r.x() + r.width(), height() - splitWidth); - } diff --git a/muse/muse/arranger/tlswidget.h b/muse/muse/arranger/tlswidget.h deleted file mode 100644 index ccdfa3b8..00000000 --- a/muse/muse/arranger/tlswidget.h +++ /dev/null @@ -1,83 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#ifndef __TLSWIDGET_H__ -#define __TLSWIDGET_H__ - -class Track; -class ArrangerTrack; -class CtrlDialog; -class TimeCanvas; - -#include "ctrl/ctrleditor.h" - -//--------------------------------------------------------- -// TLSWidget -//--------------------------------------------------------- - -class TLSWidget : public QWidget, public CtrlEditor { - Q_OBJECT - - enum { S_NORMAL, S_DRAGTOP, S_DRAGBOTTOM, S_DRAG }; - int state; - - int trackIdx; - int starty; - Track* _track; // editor canvas is associated to this track - Track* _ctrlTrack; // track were ctrl belongs to - TimeCanvas* _tc; - QToolButton* ctrlList; - QLineEdit* nameEdit; - ArrangerTrack* at; - - TimeCanvas* tc() const { return _tc; } - Ctrl* ctrl() const; - int cheight() const; - - virtual void paintEvent(QPaintEvent*); - virtual void mousePressEvent(QMouseEvent*); - virtual void mouseReleaseEvent(QMouseEvent*); - virtual void mouseMoveEvent(QMouseEvent*); - - private slots: - void labelMinusClicked(); - bool showControllerList(); - void selectionChanged(); - void configChanged(); - void controllerListChanged(int); - void autoReadChanged(); - - signals: - void minusClicked(TLSWidget*); - void controllerChanged(int); - void startDrag(int idx); - void drag(int idx, int); - - public: - TLSWidget(Track*, ArrangerTrack*, TimeCanvas* tc); - Track* track() const { return _track; } - Track* ctrlTrack() const { return _ctrlTrack; } - bool setCtrl(int ctrl); - void setIdx(int n) { trackIdx = n; } - }; - -#endif - - diff --git a/muse/muse/arranger/tlwidget.cpp b/muse/muse/arranger/tlwidget.cpp deleted file mode 100644 index fdf08d0b..00000000 --- a/muse/muse/arranger/tlwidget.cpp +++ /dev/null @@ -1,641 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#include "song.h" -#include "track.h" -#include "tlwidget.h" -#include "tlwlayout.h" -#include "tllineedit.h" -#include "icons.h" -#include "arranger.h" -#include "widgets/simplebutton.h" -#include "muse.h" -#include "trelement.h" -#include "gconfig.h" -#include "widgets/utils.h" -#include "trackdrag.h" -#include "synth.h" -#include "widgets/outportcombo.h" -#include "audio.h" -#include "midioutport.h" -#include "instruments/minstrument.h" - -//--------------------------------------------------------- -// TLWidget -//--------------------------------------------------------- - -TLWidget::TLWidget(Track* t, TrGroupList* tgl) - { - setAttribute(Qt::WA_OpaquePaintEvent); - setAutoFillBackground(true); - - setMouseTracking(true); - - state = S_NORMAL; - off = 0; - tel = tgl; - _track = t; - outPort = 0; - - bgColor = _track->ccolor(); - selectBgColor = bgColor.light(); - - QPalette p(palette()); - p.setColor(QPalette::Window, bgColor); - p.setColor(QPalette::Base, bgColor); - setPalette(p); - - l = new TLWidgetLayout(this); - configChanged(); - - connect(_track, SIGNAL(selectionChanged(bool)), SLOT(selectionChanged())); - setAcceptDrops(true); - connect(muse, SIGNAL(configChanged()), SLOT(configChanged())); - } - -//--------------------------------------------------------- -// selectionChanged -//--------------------------------------------------------- - -void TLWidget::selectionChanged() - { - update(); - } - -//--------------------------------------------------------- -// nameChanged -//--------------------------------------------------------- - -void TLWidget::nameChanged(QString s) - { - song->changeTrackName(_track, s); - nameEdit->setCursorPosition(0); - } - -//--------------------------------------------------------- -// selectTL -//--------------------------------------------------------- - -void TLWidget::select() - { - setFocus(); - song->selectTrack(_track); - } - -//--------------------------------------------------------- -// labelPlusClicked -//--------------------------------------------------------- - -void TLWidget::labelPlusClicked() - { - emit plusClicked(this); - } - -//--------------------------------------------------------- -// mousePressEvent -//--------------------------------------------------------- - -void TLWidget::mousePressEvent(QMouseEvent* ev) - { - enum { - CMD_REMOVE_TRACK, CMD_COPY_TRACK, CMD_SHOW_AUDIO_GUI, - CMD_SHOW_MIDI_GUI - }; - int button = ev->button(); - if (button == Qt::RightButton) { - QMenu* menu = new QMenu(this); - QAction* a = getAction("delete", this); - menu->addAction(a); - a->setData(CMD_REMOVE_TRACK); - if (_track->type() == Track::MIDI || _track->type() == Track::WAVE) { - a = menu->addAction(tr("Copy Track")); - a->setData(CMD_COPY_TRACK); - } - if (_track->type() == Track::AUDIO_SOFTSYNTH) { - SynthI* s = (SynthI*) _track; - if (s->hasGui()) { - menu->addSeparator(); - a = menu->addAction(tr("Show Gui")); - a->setData(CMD_SHOW_AUDIO_GUI); - a->setCheckable(true); - a->setChecked(s->guiVisible()); - } - } - else if (_track->type() == Track::MIDI_SYNTI) { - MidiSynti* s = (MidiSynti*) _track; - if (s->hasGui()) { - menu->addSeparator(); - a = menu->addAction(tr("Show Gui")); - a->setData(CMD_SHOW_MIDI_GUI); - a->setCheckable(true); - a->setChecked(s->guiVisible()); - } - } - - a = menu->exec(ev->globalPos()); - if (!a) - return; - int rv = a->data().toInt(); - switch (rv) { - default: - break; - case CMD_REMOVE_TRACK: - song->removeTrack(_track); - break; - case CMD_COPY_TRACK: - { - int idx = song->tracks()->indexOf(_track); - if (_track->type() == Track::MIDI) { - MidiTrack* t = new MidiTrack(); - t->clone((MidiTrack*)_track); - song->cmdInsertTrack(t, idx); - } - else { - WaveTrack* t = new WaveTrack(); - t->clone((WaveTrack*)_track); - song->cmdInsertTrack(t, idx); - } - } - break; - case CMD_SHOW_AUDIO_GUI: - { - SynthI* s = (SynthI*) _track; - s->showGui(!s->guiVisible()); - } - break; - case CMD_SHOW_MIDI_GUI: - { - MidiSynti* s = (MidiSynti*) _track; - s->showGui(!s->guiVisible()); - } - break; - } - return; - } - int y = ev->pos().y(); - int wh = height(); - starty = ev->globalPos().y(); - if (y > (wh - splitWidth)) { - state = S_DRAGBOTTOM; - emit startDrag(trackIdx); - } - else { - state = S_DRAG; - startDragPos = ev->pos(); - startDragTime = QTime::currentTime(); - select(); - } - } - -//--------------------------------------------------------- -// mouseReleaseEvent -//--------------------------------------------------------- - -void TLWidget::mouseReleaseEvent(QMouseEvent*) - { - state = S_NORMAL; - } - -//--------------------------------------------------------- -// mouseMoveEvent -//--------------------------------------------------------- - -void TLWidget::mouseMoveEvent(QMouseEvent* ev) - { - QPoint pos(ev->pos()); - - if (state == S_DRAGBOTTOM) - emit drag(trackIdx, ev->globalPos().y() - starty); - else if (state == S_DRAG) { - int t = startDragTime.msecsTo(QTime::currentTime()); - bool dragActive = (startDragPos - pos).manhattanLength() > - QApplication::startDragDistance() - || t > QApplication::startDragTime(); - if (dragActive) { - QDrag* d = new TrackDrag(_track, this); - d->start(Qt::MoveAction); - state = S_NORMAL; - } - } - else { - int y = pos.y(); - int wh = height(); - if (y > (wh - splitWidth)) - setCursor(Qt::SizeVerCursor); - else - setCursor(Qt::ArrowCursor); - } - } - -//--------------------------------------------------------- -// configChanged -//--------------------------------------------------------- - -void TLWidget::configChanged() - { - l->clear(); - wlist.clear(); - nameEdit = 0; - record = 0; - off = 0; - outChannel = 0; - outPort = 0; - - label = new QLabel; - label->setObjectName("trackLabel"); - l->addWidget(label); - label->setIndent(3); - - label->setText(_track->cname()); - label->setFixedHeight(11); - - plus = newPlusButton(); - l->addWidget(plus); - plus->setToolTip(tr("Add Subtrack")); - connect(plus, SIGNAL(clicked()), SLOT(labelPlusClicked())); - - for (iTrGroup i = tel->begin(); i != tel->end(); ++i) { - TrElementList& el = *i; - iTrElement k; - for (k = el.begin(); k != el.end(); ++k) { - int id = (*k)->id; - switch(id) { - case TR_NAME: - nameEdit = new TLLineEdit(_track->name(), this); - nameEdit->setFixedHeight(trackRowHeight); - connect(nameEdit, SIGNAL(contentChanged(QString)), SLOT(nameChanged(QString))); - connect(nameEdit, SIGNAL(mousePress()), SLOT(select())); - connect(_track, SIGNAL(nameChanged(const QString&)), nameEdit, SLOT(setText(const QString&))); - nameEdit->setToolTip(_track->clname() + " Name"); - l->addWidget(nameEdit); - wlist.push_back(nameEdit); - break; - - case TR_INSTRUMENT: - { - instrument = new QComboBox(this); - instrument->setFixedHeight(trackRowHeight); - MidiOutPort* op = (MidiOutPort*)_track; - MidiInstrument* mi = op->instrument(); - int idx = 0; - int curIdx = 0; - for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) { - instrument->addItem((*i)->iname()); - if ((*i)->iname() == mi->iname()) - curIdx = idx; - } - instrument->setCurrentIndex(curIdx); - connect(instrument, SIGNAL(activated(int)), SLOT(instrumentSelected(int))); - connect(op, SIGNAL(instrumentChanged()), SLOT(instrumentChanged())); - l->addWidget(instrument); - wlist.push_back(instrument); - } - break; - - case TR_PATCH: - { - // Ctrl* ctrl = _track->getController(CTRL_PROGRAM); - } - break; - - case TR_OFF: - { - off = newOffButton(); - off->setFixedSize(trackRowHeight, trackRowHeight); - off->setChecked(_track->off()); - connect(off, SIGNAL(clicked(bool)), SLOT(offToggled(bool))); - connect(_track, SIGNAL(offChanged(bool)), this, SLOT(updateOffState())); - l->addWidget(off); - wlist.push_back(off); - } - break; - - case TR_DRUMMAP: - { - SimpleButton* dm = newDrumMapButton(); - dm->setFixedSize(trackRowHeight, trackRowHeight); - dm->setChecked(((MidiTrack*)_track)->useDrumMap()); - connect(dm, SIGNAL(clicked(bool)), SLOT(drumMapToggled(bool))); - connect(_track, SIGNAL(useDrumMapChanged(bool)), dm, SLOT(setChecked(bool))); - l->addWidget(dm); - wlist.push_back(dm); - } - break; - - case TR_MUTE: - { - SimpleButton* mute = newMuteButton(); - mute->setFixedSize(trackRowHeight, trackRowHeight); - mute->setChecked(_track->isMute()); - connect(mute, SIGNAL(clicked(bool)), SLOT(muteToggled(bool))); - connect(_track, SIGNAL(muteChanged(bool)), mute, SLOT(setChecked(bool))); - l->addWidget(mute); - wlist.push_back(mute); - } - break; - - case TR_SOLO: - { - SimpleButton* solo = newSoloButton(); - solo->setFixedSize(trackRowHeight, trackRowHeight); - solo->setChecked(_track->solo()); - connect(solo, SIGNAL(clicked(bool)), SLOT(soloToggled(bool))); - connect(_track, SIGNAL(soloChanged(bool)), solo, SLOT(setChecked(bool))); - l->addWidget(solo); - wlist.push_back(solo); - } - break; - - case TR_MONITOR: - { - SimpleButton* monitor = newMonitorButton(); - monitor->setFixedSize(trackRowHeight+4, trackRowHeight); - monitor->setChecked(_track->monitor()); - connect(monitor, SIGNAL(clicked(bool)), SLOT(monitorToggled(bool))); - connect(_track, SIGNAL(monitorChanged(bool)), monitor, SLOT(setChecked(bool))); - l->addWidget(monitor); - wlist.push_back(monitor); - } - break; - - case TR_RECORD: - { - record = newRecordButton(); - record->setFixedSize(trackRowHeight, trackRowHeight); - record->setChecked(_track->recordFlag()); - connect(record, SIGNAL(clicked(bool)), SLOT(recordToggled(bool))); - connect(_track, SIGNAL(recordChanged(bool)), record, SLOT(setChecked(bool))); - l->addWidget(record); - wlist.push_back(record); - } - break; - - case TR_AREAD: - { - SimpleButton* b = newAutoReadButton(); - b->setFixedSize(trackRowHeight, trackRowHeight); - b->setChecked(_track->autoRead()); - connect(b, SIGNAL(clicked(bool)), SLOT(autoReadToggled(bool))); - connect(_track, SIGNAL(autoReadChanged(bool)), b, SLOT(setChecked(bool))); - l->addWidget(b); - wlist.push_back(b); - } - break; - - case TR_AWRITE: - { - SimpleButton* b = newAutoWriteButton(); - b->setFixedSize(trackRowHeight, trackRowHeight); - b->setChecked(_track->autoWrite()); - connect(b, SIGNAL(clicked(bool)), SLOT(autoWriteToggled(bool))); - connect(_track, SIGNAL(autoWriteChanged(bool)), b, SLOT(setChecked(bool))); - l->addWidget(b); - wlist.push_back(b); - } - break; - - case TR_OCHANNEL: - { - outChannel = new QSpinBox(this); - outChannel->setFixedSize(45, trackRowHeight); - outChannel->setRange(1, 16); - outChannel->setValue(((MidiTrack*)_track)->channelNo() + 1); - outChannel->setToolTip(tr("Midi Output Channel")); - l->addWidget(outChannel); - wlist.push_back(outChannel); - connect(outChannel, SIGNAL(valueChanged(int)), SLOT(setChannel(int))); - connect((MidiTrack*)_track, SIGNAL(channelChanged(int)), SLOT(channelChanged(int))); - } - break; - - default: - printf("TLWidget:: unknown element %d\n", id); - break; - } - } - } - updateOffState(); - selectionChanged(); // update selection state - l->update(); - } - -//--------------------------------------------------------- -// recordToggled -//--------------------------------------------------------- - -void TLWidget::recordToggled(bool val) - { - song->setRecordFlag(_track, !val); - } - -//--------------------------------------------------------- -// muteToggled -//--------------------------------------------------------- - -void TLWidget::muteToggled(bool val) - { - song->setMute(_track, val); - } - -//--------------------------------------------------------- -// monitorToggled -//--------------------------------------------------------- - -void TLWidget::monitorToggled(bool val) - { - _track->setMonitor(val); - } - -//--------------------------------------------------------- -// drumMapToggled -//--------------------------------------------------------- - -void TLWidget::drumMapToggled(bool val) - { - ((MidiTrack*)_track)->setUseDrumMap(val); - } - -//--------------------------------------------------------- -// offToggled -//--------------------------------------------------------- - -void TLWidget::offToggled(bool val) - { - song->setOff(_track, !val); - } - -//--------------------------------------------------------- -// soloToggled -//--------------------------------------------------------- - -void TLWidget::soloToggled(bool val) - { - song->setSolo(_track, val); - } - -//--------------------------------------------------------- -// autoReadToggled -//--------------------------------------------------------- - -void TLWidget::autoReadToggled(bool val) - { - song->setAutoRead(_track, val); - } - -//--------------------------------------------------------- -// autoWriteToggled -//--------------------------------------------------------- - -void TLWidget::autoWriteToggled(bool val) - { - song->setAutoWrite(_track, val); - } - -//--------------------------------------------------------- -// setOutPort -//--------------------------------------------------------- - -void TLWidget::setOutPort(int n) - { - outPort->setCurrentIndex(n); - } - -//--------------------------------------------------------- -// dragEnterEvent -//--------------------------------------------------------- - -void TLWidget::dragEnterEvent(QDragEnterEvent* event) - { - if (TrackDrag::canDecode(event)) - event->acceptProposedAction(); - } - -//--------------------------------------------------------- -// dropEvent -//--------------------------------------------------------- - -void TLWidget::dropEvent(QDropEvent* event) - { - Track* t; - TrackDrag::decode(event, t); - if (_track != t) - emit moveTrack(t, _track); - event->acceptProposedAction(); - } - -//--------------------------------------------------------- -// updateOffState -//--------------------------------------------------------- - -void TLWidget::updateOffState() - { - bool val = !_track->off(); - std::vector::iterator i = wlist.begin(); - for (; i != wlist.end(); ++i) { - if ((*i) != off) - (*i)->setEnabled(val); - } - if (off) - off->setChecked(!val); - } - -//--------------------------------------------------------- -// instrumentSelected -//--------------------------------------------------------- - -void TLWidget::instrumentSelected(int n) - { - MidiOutPort* op = (MidiOutPort*)_track; - int idx = 0; - for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) { - if (idx == n) { - op->setInstrument(*i); - break; - } - } - } - -//--------------------------------------------------------- -// instrumentChanged -//--------------------------------------------------------- - -void TLWidget::instrumentChanged() - { - MidiOutPort* op = (MidiOutPort*)_track; - MidiInstrument* mi = op->instrument(); - int idx = 0; - for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) { - if (*i == mi) { - instrument->setCurrentIndex(idx); - break; - } - } - } - -//--------------------------------------------------------- -// paintEvent -//--------------------------------------------------------- - -void TLWidget::paintEvent(QPaintEvent* ev) - { - QPainter p(this); - QRect r(ev->rect()); - QColor color(_track->selected() ? selectBgColor : bgColor); - p.fillRect(r, color); - - paintHLine(p, r.x(), r.x() + r.width(), height() - splitWidth); - QPalette pl = nameEdit->palette(); - pl.setColor(QPalette::Window, color); - pl.setColor(QPalette::Base, color); - nameEdit->setPalette(pl); - - // The selected track will get a 4 pixel red bar to the left - if ( _track->selected()) { - QColor color(200,10,10); - QRect qr(0, 0, 4, r.height()-splitWidth); - p.fillRect(qr, color); - } - } - -//--------------------------------------------------------- -// channelChanged -// SLOT: callend when channel routing of track has -// changed -// - channel starts counting at 0 -//--------------------------------------------------------- - -void TLWidget::channelChanged(int channel) - { - if (outChannel->value() == channel + 1) - return; - outChannel->setValue(channel + 1); - } - -//--------------------------------------------------------- -// setChannel -// - called when channel spinbox value changed -// - channel starts counting at 1 -//--------------------------------------------------------- - -void TLWidget::setChannel(int channel) - { - ((MidiTrack*)_track)->setChannel(channel - 1); - } - diff --git a/muse/muse/arranger/tlwidget.h b/muse/muse/arranger/tlwidget.h deleted file mode 100644 index fbe428e2..00000000 --- a/muse/muse/arranger/tlwidget.h +++ /dev/null @@ -1,105 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#ifndef __TLWIDGET_H__ -#define __TLWIDGET_H__ - -class Track; -class TrGroupList; -class TLWidgetLayout; -class SimpleButton; - -//--------------------------------------------------------- -// TLWidget -//--------------------------------------------------------- - -class TLWidget : public QWidget { - Q_OBJECT - - enum { S_NORMAL, S_DRAGBOTTOM, S_DRAG }; - int state; - - int trackIdx; - int starty; - Track* _track; - QColor bgColor; - QColor selectBgColor; - - QLineEdit* nameEdit; - TLWidgetLayout* l; - TrGroupList* tel; - QSpinBox* outChannel; - QComboBox* outPort; - SimpleButton* off; - SimpleButton* plus; - SimpleButton* record; - std::vector wlist; - QComboBox* instrument; - QLabel* label; - - QTime startDragTime; - QPoint startDragPos; - - virtual void paintEvent(QPaintEvent*); - virtual void mousePressEvent(QMouseEvent*); - virtual void mouseReleaseEvent(QMouseEvent*); - virtual void mouseMoveEvent(QMouseEvent*); - virtual void dragEnterEvent(QDragEnterEvent*); - virtual void dropEvent(QDropEvent*); - - signals: - void startDrag(int idx); - void drag(int idx, int); - - private slots: - void nameChanged(QString); - void labelPlusClicked(); - void configChanged(); - void recordToggled(bool); - void muteToggled(bool); - void offToggled(bool); - void soloToggled(bool); - void monitorToggled(bool); - void drumMapToggled(bool); - void selectionChanged(); - void setOutPort(int); - void autoReadToggled(bool val); - void autoWriteToggled(bool val); - void instrumentSelected(int); - void instrumentChanged(); - void updateOffState(); - void channelChanged(int); - void setChannel(int); - - public slots: - void select(); - - signals: - void plusClicked(TLWidget*); - void moveTrack(Track* src, Track* dst); - - public: - TLWidget(Track* t, TrGroupList*); - Track* track() const { return _track; } - void setIdx(int n) { trackIdx = n; } - }; - -#endif - diff --git a/muse/muse/arranger/tlwlayout.cpp b/muse/muse/arranger/tlwlayout.cpp deleted file mode 100644 index 076f07cf..00000000 --- a/muse/muse/arranger/tlwlayout.cpp +++ /dev/null @@ -1,144 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#include "tlwlayout.h" -#include "arranger.h" -#include "gui.h" - -//--------------------------------------------------------- -// TLWidgetLayout -//--------------------------------------------------------- - -TLWidgetLayout::TLWidgetLayout(QWidget *parent) - : QLayout(parent) - { - setMargin(0); - setSpacing(0); - } - -TLWidgetLayout::TLWidgetLayout() - { - setMargin(0); - setSpacing(0); - } - -//--------------------------------------------------------- -// takeAt -//--------------------------------------------------------- - -QLayoutItem *TLWidgetLayout::takeAt(int index) - { - if (index >= 0 && index < itemList.size()) - return itemList.takeAt(index); - else - return 0; - } - -//--------------------------------------------------------- -// setGeometry -//--------------------------------------------------------- - -void TLWidgetLayout::setGeometry(const QRect &rect) - { - int n = itemList.size(); - if (n < 2) - return; - - static const int labelWidth = 50; - int x1 = rect.x() + labelWidth; - int x2 = rect.x() + rect.width(); - int y = rect.y() + 1; - int y2 = y + rect.height() - splitWidth; - int dh = trackRowHeight; - - QLayoutItem* item = itemList.at(0); - QSize size(item->sizeHint()); - item->setGeometry(QRect(rect.x(), rect.y(), size.width(), size.height())); - - item = itemList.at(1); - item->setGeometry(QRect(x1 - 18, y2 - 19, 18, 18)); - - itemList.at(2)->setGeometry(QRect(x1, y, x2-x1, dh)); - if (n <= 3) - return; - - y += dh; - if ((y + itemList.at(3)->sizeHint().height()) > y2) { - for (int i = 3; i < n; ++i) - itemList.at(i)->setGeometry(QRect(-1000, -1000, 0, 0)); - return; - } - int x = x1; - - for (int i = 3; i < n; ++i) { - QLayoutItem *item = itemList.at(i); - QSize size(item->sizeHint()); - - if ((x > x1) && ((x + size.width()) > x2)) { - x = x1; - y += dh; - if ((y + size.height()) > y2) { - for (; i < n; ++i) - itemList.at(i)->setGeometry(QRect(-1000, -1000, 0, 0)); - return; - } - } - item->setGeometry(QRect(x, y, size.width(), dh)); - x += size.width(); - } - } - -//--------------------------------------------------------- -// sizeHint -//--------------------------------------------------------- - -QSize TLWidgetLayout::sizeHint() const - { - return minimumSize(); - } - -//--------------------------------------------------------- -// minimumSize -//--------------------------------------------------------- - -QSize TLWidgetLayout::minimumSize() const - { - QSize size; - QLayoutItem *item; - foreach (item, itemList) - size = size.expandedTo(item->minimumSize()); - - size += QSize(2*margin(), 2*margin()); - return size; - } - -//--------------------------------------------------------- -// clear -//--------------------------------------------------------- - -void TLWidgetLayout::clear() - { - QLayoutItem* child; - while ((child = takeAt(0)) != 0) { - delete child->widget(); - delete child; - } - } - diff --git a/muse/muse/arranger/tlwlayout.h b/muse/muse/arranger/tlwlayout.h deleted file mode 100644 index 1a9cc914..00000000 --- a/muse/muse/arranger/tlwlayout.h +++ /dev/null @@ -1,51 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#ifndef __TLWLAYOUT_H__ -#define __TLWLAYOUT_H__ - -//--------------------------------------------------------- -// TLWidgetLayout -//--------------------------------------------------------- - -class TLWidgetLayout : public QLayout { - QList itemList; - - int doLayout(const QRect& rect, bool testOnly) const; - - public: - TLWidgetLayout(QWidget* parent); - TLWidgetLayout(); - ~TLWidgetLayout() { clear(); } - - void addItem(QLayoutItem* item) { itemList.append(item); } - Qt::Orientations expandingDirections() const { return 0; } - bool hasHeightForWidth() const { return false; } - int count() const { return itemList.size(); } - QSize minimumSize() const; - void setGeometry(const QRect &rect); - QSize sizeHint() const; - QLayoutItem *itemAt(int index) const { return itemList.value(index); } - QLayoutItem *takeAt(int index); - void clear(); - }; - -#endif - diff --git a/muse/muse/arranger/trackdrag.cpp b/muse/muse/arranger/trackdrag.cpp deleted file mode 100644 index beab87dd..00000000 --- a/muse/muse/arranger/trackdrag.cpp +++ /dev/null @@ -1,61 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#include "trackdrag.h" - -class Track; -const char TrackDrag::type[] = "application/muse/track"; - -//--------------------------------------------------------- -// TrackDrag -//--------------------------------------------------------- - -TrackDrag::TrackDrag(Track* track, QWidget* src) - : QDrag(src) - { - QByteArray a((char*)&track, sizeof(track)); - QMimeData* mimeData = new QMimeData; - mimeData->setData(type, a); - setMimeData(mimeData); - } - -//--------------------------------------------------------- -// canDecode -//--------------------------------------------------------- - -bool TrackDrag::canDecode(const QMimeSource* s) - { - return !strcmp(s->format(0), type); - } - -//--------------------------------------------------------- -// decode -//--------------------------------------------------------- - -bool TrackDrag::decode(const QMimeSource* s, Track*& p) - { - QByteArray a = s->encodedData(type); - p = (Track*)((a[0] & 0xff) - | (a[1] & 0xff) << 8 - | (a[2] & 0xff) << 16 - | (a[3] & 0xff) << 24); - return true; - } - diff --git a/muse/muse/arranger/trackdrag.h b/muse/muse/arranger/trackdrag.h deleted file mode 100644 index 083a94b3..00000000 --- a/muse/muse/arranger/trackdrag.h +++ /dev/null @@ -1,42 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#ifndef __TRACKDRAG_H__ -#define __TRACKDRAG_H__ - -class Track; - -//--------------------------------------------------------- -// TrackDrag -//--------------------------------------------------------- - -class TrackDrag : public QDrag { - static const char type[]; - Q_OBJECT - - public: - TrackDrag(Track*, QWidget* src); - static bool canDecode(const QMimeSource*); - static bool decode(const QMimeSource* s, Track*& p); - }; - - -#endif - diff --git a/muse/muse/arranger/trackinfo.cpp b/muse/muse/arranger/trackinfo.cpp deleted file mode 100644 index 1a62b1c0..00000000 --- a/muse/muse/arranger/trackinfo.cpp +++ /dev/null @@ -1,553 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#include "arranger.h" -#include "widgets/outportcombo.h" -#include "instruments/minstrument.h" -#include "midiedit/drummap.h" -#include "midictrl.h" -#include "song.h" -#include "trackinfo.h" -#include "synth.h" -#include "tllineedit.h" -#include "audio.h" -#include "gui.h" -#include "midioutport.h" -#include "midiinport.h" - -static QColor labelColor(140, 140, 255); - -//--------------------------------------------------------- -// createTrackInfo -//--------------------------------------------------------- - -TrackInfo* Arranger::createTrackInfo() - { - Track::TrackType t = _curTrack->type(); - switch (t) { - case Track::MIDI: return new MidiTrackInfo(); - case Track::AUDIO_OUTPUT: return new AudioOutputInfo(); - case Track::AUDIO_GROUP: return new AudioGroupInfo(); - case Track::WAVE: return new WaveTrackInfo(); - case Track::AUDIO_INPUT: return new AudioInputInfo(); - case Track::AUDIO_SOFTSYNTH: return new SynthIInfo(); - case Track::MIDI_OUT: return new MidiOutPortInfo(); - case Track::MIDI_IN: return new MidiInPortInfo(); - case Track::MIDI_SYNTI: return new MidiSynthIInfo(); - default: - printf("Arranger::createTrackInfo: type %d\n", t); - abort(); - } - } - -//--------------------------------------------------------- -// TrackInfo -//--------------------------------------------------------- - -TrackInfo::TrackInfo() - : QWidget() - { - track = 0; - label = new QLabel; - label->setToolTip(tr("Track Type")); - label->setLineWidth(2); - label->setFrameStyle(QFrame::Panel | QFrame::Raised); - label->setAutoFillBackground(true); - QPalette p = label->palette(); - p.setColor(QPalette::Background, labelColor); - label->setPalette(p); - - name = new TLLineEdit(""); - name->setToolTip(tr("Track Name")); - name->setMaximumHeight(24); - - grid = new QGridLayout; - grid->setMargin(0); - grid->setSpacing(0); - setLayout(grid); - - grid->addWidget(label, 0, 0, 1, 2); - grid->addWidget(name, 1, 0, 1, 2); - connect(name, SIGNAL(contentChanged(QString)), SLOT(nameChanged(QString))); - connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int))); -// resize(QSize(infoWidth, height())); - } - -//--------------------------------------------------------- -// nameChanged -//--------------------------------------------------------- - -void TrackInfo::nameChanged(QString s) - { - song->changeTrackName(track, s); - name->setCursorPosition(0); - } - -//--------------------------------------------------------- -// init -//--------------------------------------------------------- - -void TrackInfo::init(Track* t) - { - track = t; - if (t == 0) - return; - label->setText(track->clname()); - name->setText(track->name()); - connect(track, SIGNAL(nameChanged(const QString&)), name, SLOT(setText(const QString&))); - } - -//--------------------------------------------------------- -// songChanged -//--------------------------------------------------------- - -void TrackInfo::songChanged(int val) - { - if ((val & SC_ROUTE) && track) - init(track); - } - -//--------------------------------------------------------- -// MidiTrackInfo -//--------------------------------------------------------- - -MidiTrackInfo::MidiTrackInfo() - : TrackInfo() - { - QWidget* midiTrackInfo = new QWidget; - mt.setupUi(midiTrackInfo); - - QWidget* midiPortInfo = new QWidget; - mp.setupUi(midiPortInfo); - - grid->addWidget(midiTrackInfo, 2, 0, 1, 2); - - channel = new QComboBox; - channel->setMaximumHeight(24); - for (int ch = 0; ch < MIDI_CHANNELS; ++ch) - channel->addItem(tr("Channel %1").arg(ch+1), ch); - grid->addWidget(channel, 3, 0, 1, 2); - - QLabel* label = new QLabel; - label->setText(tr("Midi Port")); - label->setLineWidth(2); - label->setFrameStyle(QFrame::Panel | QFrame::Raised); - label->setAutoFillBackground(true); - QPalette p = label->palette(); - p.setColor(QPalette::Background, labelColor); - label->setPalette(p); - grid->addWidget(label, 4, 0, 1, 2); - - port = new QComboBox; - port->setMaximumHeight(24); - grid->addWidget(port, 5, 0, 1, 2); - grid->addWidget(midiPortInfo, 6, 0, 1, 2); - grid->setRowStretch(grid->rowCount(), 100); - - pop = new QMenu(mt.patch); - - connect(mt.transposition, SIGNAL(valueChanged(int)), SLOT(transpositionChanged(int))); - connect(mt.velocity, SIGNAL(valueChanged(int)), SLOT(velocityChanged(int))); - connect(mt.delay, SIGNAL(valueChanged(int)), SLOT(delayChanged(int))); - connect(mt.length, SIGNAL(valueChanged(int)), SLOT(lenChanged(int))); - connect(mt.compression, SIGNAL(valueChanged(int)), SLOT(iKomprChanged(int))); - connect(mt.patch, SIGNAL(clicked()), SLOT(patchClicked())); - connect(port, SIGNAL(activated(int)), SLOT(portSelected(int))); - connect(mp.instrument, SIGNAL(activated(int)), SLOT(instrumentSelected(int))); - connect(mp.deviceId, SIGNAL(valueChanged(int)), SLOT(deviceIdChanged(int))); - connect(song, SIGNAL(autoReadChanged(Track*,bool)), SLOT(autoChanged(Track*,bool))); - connect(song, SIGNAL(autoWriteChanged(Track*,bool)), SLOT(autoChanged(Track*,bool))); - } - -//--------------------------------------------------------- -// init -//--------------------------------------------------------- - -void MidiTrackInfo::init(Track* t) - { - MidiTrack* midiTrack = (MidiTrack*)&*t; - if (t != track) { - if (track) { - disconnect(channel, 0, track, 0); - disconnect(track, 0, channel, 0); - } - connect(channel, SIGNAL(activated(int)), midiTrack, SLOT(setChannel(int))); - connect(midiTrack,SIGNAL(channelChanged(int)), channel, SLOT(setCurrentIndex(int))); - } - - TrackInfo::init(t); - mt.transposition->setValue(midiTrack->transposition()); - mt.delay->setValue(midiTrack->delay()); - mt.length->setValue(midiTrack->len()); - mt.velocity->setValue(midiTrack->velocity()); - mt.compression->setValue(midiTrack->compression()); - - mp.instrument->clear(); - foreach(MidiInstrument* mi, midiInstruments) - mp.instrument->addItem(mi->iname()); - - RouteList* rl = track->outRoutes(); - Track* outputTrack = 0; - if (!rl->isEmpty()) - outputTrack = (*rl)[0].dst.track; - - port->clear(); - port->addItem("---", QVariant::fromValue(0)); - foreach(MidiOutPort* mp, *(song->midiOutPorts())) - port->addItem(mp->name(), QVariant::fromValue(mp)); - foreach(SynthI* s, *(song->syntis())) - port->addItem(s->name(), QVariant::fromValue(s)); - if (outputTrack) { - int idx = port->findText(outputTrack->name()); - port->setCurrentIndex(idx == -1 ? 0 : idx); - } - - channel->setCurrentIndex(midiTrack->channelNo()); - - connect(track, SIGNAL(controllerChanged(int)), SLOT(controllerChanged(int))); - if (outputTrack && outputTrack->type() == Track::MIDI_OUT) - connect(outputTrack, SIGNAL(instrumentChanged()), SLOT(instrumentChanged())); - - instrumentChanged(); // setup instrument - - // enable instrument selection only for tracks routed to a - // midi out port: - mp.instrument->setEnabled(outputTrack && (outputTrack->type() == Track::MIDI_OUT)); - - if (!rl->isEmpty()) { - mp.deviceId->setValue(midiTrack->deviceId()); - autoChanged(track, false); // update enable - int val = midiTrack->ctrlVal(CTRL_PROGRAM).i; - int channelno = midiTrack->channelNo(); - mt.patch->setText(midiTrack->instrument()->getPatchName(channelno, val)); - } - else { - channel->setCurrentIndex(0); - port->setCurrentIndex(0); - mp.instrument->addItem("--"); - mp.instrument->setCurrentIndex(0); - mt.patch->setText("--"); - } - } - -//--------------------------------------------------------- -// portSelected -//--------------------------------------------------------- - -void MidiTrackInfo::portSelected(int idx) - { - QVariant v(port->itemData(idx)); - Track* outputTrack = (Track*)v.value(); - if (outputTrack == 0) - return; - RouteList* rl = track->outRoutes(); - if (rl->isEmpty()) - return; - Route r = (*rl)[0]; - audio->msgRemoveRoute(r); - r.dst.track = outputTrack; - audio->msgAddRoute(r); - song->update(SC_ROUTE); - } - -//--------------------------------------------------------- -// controllerChanged -//--------------------------------------------------------- - -void MidiTrackInfo::controllerChanged(int id) - { - if (id == CTRL_PROGRAM) { - MidiInstrument* mi = track->instrument(); - int val = track->ctrlVal(id).i; - mt.patch->setText(mi->getPatchName(((MidiTrack*)&*track)->channelNo(), val)); - } - } - -//--------------------------------------------------------- -// instrumentChanged -//--------------------------------------------------------- - -void MidiTrackInfo::instrumentChanged() - { - MidiInstrument* mi = track->instrument(); - mp.instrument->setCurrentIndex(midiInstruments.indexOf(mi)); - } - -//--------------------------------------------------------- -// autoChanged -//--------------------------------------------------------- - -void MidiTrackInfo::autoChanged(Track* t, bool) - { - if (t != track) - return; - bool ar = t->autoRead(); - bool aw = t->autoWrite(); - bool en = !ar || (ar && aw); - mt.patch->setEnabled(en); - } - -//--------------------------------------------------------- -// transpositionChanged -//--------------------------------------------------------- - -void MidiTrackInfo::transpositionChanged(int val) - { - ((MidiTrack*)&*track)->setTransposition(val); - } - -//--------------------------------------------------------- -// patchClicked -//--------------------------------------------------------- - -void MidiTrackInfo::patchClicked() - { - MidiInstrument* mi = track->instrument(); - mi->populatePatchPopup(pop, 0); - - QAction* rv = pop->exec(mt.patch->mapToGlobal(QPoint(10,5))); - if (rv != 0) { - CVal cval; - cval.i = rv->data().toInt(); - song->setControllerVal(track, CTRL_PROGRAM, cval); - } - } - -//--------------------------------------------------------- -// instrumentSelected -//--------------------------------------------------------- - -void MidiTrackInfo::instrumentSelected(int n) - { - RouteList* rl = track->outRoutes(); - if (rl->isEmpty()) - return; - Track* outTrack = (*rl)[0].dst.track; - if (outTrack->type() == Track::MIDI_OUT) - ((MidiOutPort*)outTrack)->setInstrument(midiInstruments[n]); - } - -//--------------------------------------------------------- -// velocityChanged -//--------------------------------------------------------- - -void MidiTrackInfo::velocityChanged(int val) - { - ((MidiTrack*)&*track)->setVelocity(val); - } - -//--------------------------------------------------------- -// delayChanged -//--------------------------------------------------------- - -void MidiTrackInfo::delayChanged(int val) - { - ((MidiTrack*)&*track)->setDelay(val); - } - -//--------------------------------------------------------- -// lenChanged -//--------------------------------------------------------- - -void MidiTrackInfo::lenChanged(int val) - { - ((MidiTrack*)&*track)->setLen(val); - } - -//--------------------------------------------------------- -// iKomprChanged -//--------------------------------------------------------- - -void MidiTrackInfo::iKomprChanged(int val) - { - ((MidiTrack*)&*track)->setCompression(val); - } - -//--------------------------------------------------------- -// deviceIdChanged -//--------------------------------------------------------- - -void MidiTrackInfo::deviceIdChanged(int val) - { - ((MidiTrack*)&*track)->setDeviceId(val); - } - -//--------------------------------------------------------- -// AudioOutputInfo -//--------------------------------------------------------- - -AudioOutputInfo::AudioOutputInfo() - : TrackInfo() - { - grid->setRowStretch(grid->rowCount(), 100); - } - -//--------------------------------------------------------- -// AudioInputInfo -//--------------------------------------------------------- - -AudioInputInfo::AudioInputInfo() - : TrackInfo() - { - grid->setRowStretch(grid->rowCount(), 100); - } - -//--------------------------------------------------------- -// AudioGroupInfo -//--------------------------------------------------------- - -AudioGroupInfo::AudioGroupInfo() - : TrackInfo() - { - grid->setRowStretch(grid->rowCount(), 100); - } - -//--------------------------------------------------------- -// AudioAuxInfo -//--------------------------------------------------------- - -AudioAuxInfo::AudioAuxInfo() - : TrackInfo() - { - grid->setRowStretch(grid->rowCount(), 100); - } - -//--------------------------------------------------------- -// WaveTrackInfo -//--------------------------------------------------------- - -WaveTrackInfo::WaveTrackInfo() - : TrackInfo() - { - grid->setRowStretch(grid->rowCount(), 100); - } - -//--------------------------------------------------------- -// SynthIInfo -//--------------------------------------------------------- - -SynthIInfo::SynthIInfo() - : TrackInfo() - { - grid->setRowStretch(grid->rowCount(), 100); - } - -//--------------------------------------------------------- -// MidiSynthIInfo -//--------------------------------------------------------- - -MidiSynthIInfo::MidiSynthIInfo() - : TrackInfo() - { - grid->setRowStretch(grid->rowCount(), 100); - } - -//--------------------------------------------------------- -// MidiOutPortInfo -//--------------------------------------------------------- - -MidiOutPortInfo::MidiOutPortInfo() - : TrackInfo() - { - QWidget* midiPortInfo = new QWidget; - mp.setupUi(midiPortInfo); - grid->addWidget(midiPortInfo, 2, 0, 1, 2); - - grid->setRowStretch(grid->rowCount(), 100); - - connect(mp.instrument, SIGNAL(activated(int)), SLOT(instrumentSelected(int))); - connect(mp.deviceId, SIGNAL(valueChanged(int)), SLOT(deviceIdChanged(int))); - } - -//--------------------------------------------------------- -// init -//--------------------------------------------------------- - -void MidiOutPortInfo::init(Track* t) - { - TrackInfo::init(t); - - MidiOutPort* op = (MidiOutPort*)&*track; - MidiInstrument* mi = op->instrument(); - int idx = 0; - int curIdx = 0; - mp.instrument->clear(); - for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) { - mp.instrument->addItem((*i)->iname()); - if ((*i)->iname() == mi->iname()) - curIdx = idx; - } - mp.instrument->setCurrentIndex(curIdx); - mp.deviceId->setValue(op->deviceId()); - connect(t, SIGNAL(instrumentChanged()), SLOT(instrumentChanged())); - } - -//--------------------------------------------------------- -// deviceIdChanged -//--------------------------------------------------------- - -void MidiOutPortInfo::deviceIdChanged(int val) - { - ((MidiOutPort*)&*track)->setDeviceId(val); - } - -//--------------------------------------------------------- -// instrumentChanged -//--------------------------------------------------------- - -void MidiOutPortInfo::instrumentChanged() - { - MidiOutPort* op = (MidiOutPort*)&*track; - MidiInstrument* mi = op->instrument(); - int idx = 0; - for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) { - if (*i == mi) { - mp.instrument->setCurrentIndex(idx); - break; - } - } - } - -//--------------------------------------------------------- -// instrumentSelected -//--------------------------------------------------------- - -void MidiOutPortInfo::instrumentSelected(int n) - { - MidiOutPort* op = (MidiOutPort*)&*track; - int idx = 0; - for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) { - if (idx == n) { - op->setInstrument(*i); - break; - } - } - } - -//--------------------------------------------------------- -// MidiInPortInfo -//--------------------------------------------------------- - -MidiInPortInfo::MidiInPortInfo() - : TrackInfo() - { - grid->setRowStretch(grid->rowCount(), 100); - } - diff --git a/muse/muse/arranger/trackinfo.h b/muse/muse/arranger/trackinfo.h deleted file mode 100644 index bea98d70..00000000 --- a/muse/muse/arranger/trackinfo.h +++ /dev/null @@ -1,203 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#ifndef __TRACKINFO_H__ -#define __TRACKINFO_H__ - -#include "ui_miditrackinfo.h" -#include "ui_midiportinfo.h" - -class Track; -class MidiTrack; -class AudioOutput; -class AudioInput; -class AudioGroup; -class AudioAux; -class SynthI; -class MidiInPort; -class MidiOutPort; -class MidiChannel; -class WaveTrack; -class TLLineEdit; - -//--------------------------------------------------------- -// TrackInfo -//--------------------------------------------------------- - -class TrackInfo : public QWidget { - Q_OBJECT - - QLabel* label; - TLLineEdit* name; - - protected: - QGridLayout* grid; - QPointer track; - - private slots: - void nameChanged(QString s); - void songChanged(int); - - public: - TrackInfo(); - virtual void init(Track*); - }; - -//--------------------------------------------------------- -// MidiTrackInfo -//--------------------------------------------------------- - -class MidiTrackInfo : public TrackInfo { - Q_OBJECT - - Ui::MidiTrackInfoBase mt; - Ui::MidiPortInfoBase mp; - QComboBox* port; - QComboBox* channel; - QMenu* pop; - - private slots: - void transpositionChanged(int val); - void velocityChanged(int val); - void delayChanged(int val); - void lenChanged(int val); - void iKomprChanged(int val); - void patchClicked(); - void instrumentSelected(int); - void instrumentChanged(); - void autoChanged(Track*,bool); - void controllerChanged(int); - void portSelected(int); - void deviceIdChanged(int); - - public: - MidiTrackInfo(); - virtual void init(Track*); - }; - -//--------------------------------------------------------- -// AudioOutputInfo -//--------------------------------------------------------- - -class AudioOutputInfo : public TrackInfo { - Q_OBJECT - - public: - AudioOutputInfo(); - }; - -//--------------------------------------------------------- -// AudioInputInfo -//--------------------------------------------------------- - -class AudioInputInfo : public TrackInfo { - Q_OBJECT - - public: - AudioInputInfo(); - }; - -//--------------------------------------------------------- -// AudioGroupInfo -//--------------------------------------------------------- - -class AudioGroupInfo : public TrackInfo { - Q_OBJECT - - public: - AudioGroupInfo(); - }; - -//--------------------------------------------------------- -// AudioAuxInfo -//--------------------------------------------------------- - -class AudioAuxInfo : public TrackInfo { - Q_OBJECT - - public: - AudioAuxInfo(); - }; - -//--------------------------------------------------------- -// WaveTrackInfo -//--------------------------------------------------------- - -class WaveTrackInfo : public TrackInfo { - Q_OBJECT - - public: - WaveTrackInfo(); - }; - -//--------------------------------------------------------- -// SynthIInfo -//--------------------------------------------------------- - -class SynthIInfo : public TrackInfo { - Q_OBJECT - - public: - SynthIInfo(); - }; - -//--------------------------------------------------------- -// MidiSynthIInfo -//--------------------------------------------------------- - -class MidiSynthIInfo : public TrackInfo { - Q_OBJECT - - public: - MidiSynthIInfo(); - }; - -//--------------------------------------------------------- -// MidiOutPortInfo -//--------------------------------------------------------- - -class MidiOutPortInfo : public TrackInfo { - Q_OBJECT - - Ui::MidiPortInfoBase mp; - - private slots: - void instrumentSelected(int); - void instrumentChanged(); - void deviceIdChanged(int); - - public: - MidiOutPortInfo(); - virtual void init(Track*); - }; - -//--------------------------------------------------------- -// MidiInPortInfo -//--------------------------------------------------------- - -class MidiInPortInfo : public TrackInfo { - Q_OBJECT - - public: - MidiInPortInfo(); - }; - -#endif - diff --git a/muse/muse/arranger/trelement.h b/muse/muse/arranger/trelement.h deleted file mode 100644 index 478b5e51..00000000 --- a/muse/muse/arranger/trelement.h +++ /dev/null @@ -1,64 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#ifndef __TR_ELEMENT_H__ -#define __TR_ELEMENT_H__ - -#include "track.h" - -//--------------------------------------------------------- -// TrElement -// describes a configurable gui element of the -// track list -//--------------------------------------------------------- - -enum { - TR_NAME, TR_MUTE, TR_OFF, TR_SOLO, TR_RECORD, TR_AREAD, TR_AWRITE, - TR_OCHANNEL, TR_MONITOR, TR_DRUMMAP, TR_INSTRUMENT, TR_PATCH - }; - -struct TrElement { - int id; - int grp; // default group - char* name; - int trackMask; - - TrElement(int i, int g, char* s, int m) - : id(i), grp(g), name(s), trackMask(m) {} - }; - -//--------------------------------------------------------- -// TrGroup -// TrElements are grouped -//--------------------------------------------------------- - -typedef std::list TrElementList; -typedef TrElementList::iterator iTrElement; - -class TrGroupList : public std::list { - }; -typedef TrGroupList::iterator iTrGroup; - -extern const TrElement trElements[]; -extern const int nTrElements; -extern TrGroupList glist[Track::TRACK_TYPES]; - -#endif - diff --git a/muse/muse/canvas.cpp b/muse/muse/canvas.cpp new file mode 100644 index 00000000..614cf3e3 --- /dev/null +++ b/muse/muse/canvas.cpp @@ -0,0 +1,1187 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "canvas.h" +#include "al/al.h" +#include "al/sig.h" +#include "gconfig.h" +#include "song.h" +#include "icons.h" +#include "audio.h" +#include "partdrag.h" +#include "muse.h" +#include "midictrl.h" +#include "tlswidget.h" +#include "part.h" +#include "gui.h" + +#include + +static const int partLabelHeight = 13; +static const int handleWidth = 5; +static const int partBorderWidth = 2; + +enum { HIT_NOTHING, HIT_TRACK, HIT_PART, HIT_SUBTRACK }; + +//--------------------------------------------------------- +// PartCanvas +//--------------------------------------------------------- + +PartCanvas::PartCanvas() + : TimeCanvas(TIME_CANVAS) + { + setFocusPolicy(Qt::StrongFocus); + state = S_NORMAL; + _drawBackground = true; + lselected = -1; + starty = -1; + setMarkerList(song->marker()); + rubberBand=NULL; + connect(song, SIGNAL(markerChanged(int)), SLOT(markerChanged(int))); + } + +//--------------------------------------------------------- +// markerChanged +//--------------------------------------------------------- + +void PartCanvas::markerChanged(int val) + { + if (val == Song::MARKER_CUR) + updateRuler(); + } + +//--------------------------------------------------------- +// drawWavePart +// y0 - start of track +// th - track height +// from - x pixel coordinate start drawing +// to - x end drawing +// +// redraw area is QRect(from, y0, to-from, th) +//--------------------------------------------------------- + +void PartCanvas::drawWavePart(QPainter& p, Part* wp, int y0, int th, int from, int to) + { + int h = th/2; + int y = y0 + 1 + h; + int cc = th % 2 ? 0 : 1; + + const Pos pos(pix2pos(from)); + EventList* el = wp->events(); + for (iEvent e = el->begin(); e != el->end(); ++e) { + Event event = e->second; + SndFileR f = event.sndFile(); + if (f.isNull()) + continue; + unsigned channels = f.channels(); + if (channels == 0) { + printf("drawWavePart: channels==0! %s\n", f.finfo()->fileName().toLatin1().data()); + continue; + } + + int x1 = pos2pix(event.pos() + *wp); + int x2 = pos2pix(event.end() + *wp); + int w = x2 - x1; + if (w == 0) + continue; + + int samples = event.lenFrame(); + int xScale = (samples + w/2)/w; + int frame = pos.frame() - wp->frame() + - event.pos().frame() + event.spos(); + + if (h < 20) { + // + // combine multi channels into one waveform + // + for (int i = from; i < to; i++) { + SampleV sa[channels]; + f.read(sa, xScale, frame); + frame += xScale; + int peak = 0; + int rms = 0; + for (unsigned k = 0; k < channels; ++k) { + if (sa[k].peak > peak) + peak = sa[k].peak; + rms += sa[k].rms; + } + rms /= channels; + peak = (peak * (th-2)) >> 9; + rms = (rms * (th-2)) >> 9; + p.setPen(QColor(Qt::darkGray)); + p.drawLine(i, y - peak - cc, i, y + peak); + p.setPen(QColor(Qt::black)); + p.drawLine(i, y - rms - cc, i, y + rms); + } + } + else { + // + // multi channel display + // + h = th / (channels * 2); + int cc = th % (channels * 2) ? 0 : 1; + for (int i = from; i < to; i++) { + y = y0 + 1 + h; + SampleV sa[channels]; + f.read(sa, xScale, frame); + frame += xScale; + for (unsigned k = 0; k < channels; ++k) { + // peak = (sa[k].peak * h) / 256; + int peak = (sa[k].peak * (h - 1)) >> 8; + int rms = (sa[k].rms * (h - 1)) >> 8; + p.setPen(QColor(Qt::darkGray)); + p.drawLine(i, y - peak - cc, i, y + peak); + p.setPen(QColor(Qt::black)); + p.drawLine(i, y - rms - cc, i, y + rms); + y += 2 * h; + } + } + } + } + } + +//--------------------------------------------------------- +// paint +//--------------------------------------------------------- + +void PartCanvas::paint(QPainter& p, QRect r) + { + //printf("canvas paint %d %d %d %d\n", r.x(), r.y(), r.width(), r.height()); + QFont f = font(); + f.setPointSize(8); + p.setFont(f); + + int from = r.x(); + int to = from + r.width(); + + TrackList* tl = song->tracks(); + ArrangerTrack* at = 0; + for (iTrack i = tl->begin(); i != tl->end(); ++i) { + Track* t = *i; + at = &(t->arrangerTrack); + if (at->tw == 0) + continue; + + int y = at->tw->y(); // - splitWidth/2; + int h = at->tw->height() - 1; + + PartList* pl = t->parts(); + for (iPart ip = pl->begin(); ip != pl->end(); ++ip) { + Part* part = ip->second; + int x1 = pos2pix(*part); + int x2 = pos2pix(part->end()); + int len = x2 - x1; + + if (x2 <= from) + continue; + if (x1 > to) + break; + + QRect pr(x1, y, len, h - partBorderWidth); + bool clone = part->isClone(); + + QPen pen(QColor(100, 100, 100), partBorderWidth, clone ? Qt::DashLine : Qt::SolidLine); + QBrush brush(Qt::SolidPattern); + QLinearGradient lg(0, pr.y() - wpos.y()-r.y(), + 0, pr.y()+ 2*pr.height() -wpos.y()-r.y()); + lg.setColorAt(0, part->selected()?Qt::gray + :config.partColors[part->colorIndex()]); + lg.setColorAt(1, Qt::white); + QBrush brushLG(lg); + if (part->selected()) { + pen.setColor(config.partColors[part->colorIndex()]); + brush.setColor(config.selectPartBg); + p.setBrush(brushLG); + } + else if (part->mute()) { + pen.setColor(Qt::red); + brush.setColor(Qt::gray); + p.setBrush(brush); + } + else { + //brush.setColor(config.partColors[part->colorIndex()]); + p.setBrush(brushLG); + } + p.setPen(pen); + // + // we want to draw the rectangle without transformation + // to get equal border width horizontal and vertical + // + QRect rr(p.matrix().mapRect(pr).adjusted(1, 0, -1, 0)); + p.save(); + p.resetMatrix(); + p.drawRect(rr); + p.restore(); + + int xx1 = x1; + if (xx1 < from) + xx1 = from; + int xx2 = x2; + if (xx2 > to) + xx2 = to; + if (t->isMidiTrack()) + drawMidiPart(p, part, y, h, xx1, xx2); + else if (t->type() == Track::WAVE) + drawWavePart(p, part, y, h, xx1, xx2); + int yy = y + h - partLabelHeight; + p.drawText(x1 + 3, yy, len - 6, + partLabelHeight-1, Qt::AlignVCenter | Qt::AlignLeft, + part->name()); + + // redraw border + p.save(); + p.resetMatrix(); + p.setPen(pen); + p.setBrush(Qt::NoBrush); + p.drawRect(rr); + p.restore(); + } + + if (i != tl->begin()) { + p.setPen(QPen(Qt::lightGray, trackSeparator, Qt::SolidLine)); + p.drawLine(from, y + yTrackOffset, to, y + yTrackOffset); + } + for (iArrangerTrack i = t->subtracks.begin(); i != t->subtracks.end(); ++i) { + at = *i; + if (at->tw == 0) + continue; + TLSWidget* tls = (TLSWidget*)(at->tw); + int y = tls->y(); + // int h = tls->height(); + p.setPen(QPen(Qt::lightGray, trackSeparator, Qt::SolidLine)); + p.drawLine(from, y + yTrackOffset, to, y + yTrackOffset); + y += yTrackOffset + trackSeparator; + QPoint off(0, y); + p.translate(off); + // tls->paint(p, r); + tls->paint(p, QRect(from, 0, to-from, tls->height() - (yTrackOffset + trackSeparator))); + p.translate(-off); + } + } + if (at && at->tw) { + // draw last line + int y = at->tw->y() + at->tw->height() + yTrackOffset; + p.setPen(QPen(Qt::lightGray, trackSeparator, Qt::SolidLine)); + p.drawLine(from, y, to, y); + } + if (state == S_DRAG4 || state == S_DRAG1 || state == S_DRAG2 || state == S_DRAG5) { + p.setBrush(Qt::NoBrush); + p.setPen(QPen(QColor(Qt::red), partBorderWidth)); + p.drawRect(drag); + } + } + +//--------------------------------------------------------- +// drawMidiPart +//--------------------------------------------------------- + +void PartCanvas::drawMidiPart(QPainter& p, Part* mp, int y, int th, int from, int to) + { + p.setPen(Qt::black); + + EventList* events = mp->events(); + // iEvent ito(events->lower_bound(to)); + + iEvent ito = events->end(); +// int pos = pos2pix(*mp); + + if (config.canvasShowPartType & 2) { // show events + for (iEvent i = events->lower_bound(from); i != ito; ++i) { + EventType type = i->second.type(); + if ( + ((config.canvasShowPartEvent & 1) && (type == Note)) + || ((config.canvasShowPartEvent & 2) && (type == PAfter)) + || ((config.canvasShowPartEvent & 4) && (type == Controller)) + || ((config.canvasShowPartEvent &16) && (type == CAfter)) + || ((config.canvasShowPartEvent &64) && (type == Sysex || type == Meta)) + ) { + int t = pos2pix(*mp + i->second.pos()); + p.drawLine(t, y + 1, t, y + th - 2); + } + } + } + + else { // show Cakewalk Style + for (iEvent i = events->begin(); i != ito; ++i) { + if (i->second.type() != Note) + continue; + int x1 = pos2pix(*mp + i->second.pos()); + int x2 = pos2pix(*mp + i->second.end()); + + if (x1 > to) + break; + if (x2 < from) + continue; + + if (x2 > to) // clip to drawing area + x2 = to; + if (x1 < from) + x1 = from; + int pitch = i->second.pitch(); + int yy = y + th - (pitch * th / 127); + p.drawLine(x1, yy, x2, yy); + } + } + } + +//--------------------------------------------------------- +// searchPart +//--------------------------------------------------------- + +int PartCanvas::searchPart(const QPoint& pp) + { + Pos tp(pix2pos(pp.x())); + QPoint p(tp.tick(), pp.y() + wpos.y()); + +// printf("searchPart %d %d\n", p.x(), p.y()); + track = 0; + part = 0; + at = 0; + int yp = p.y(); + if (yp < 0) + return HIT_NOTHING; + + TrackList* tl = song->tracks(); + iTrack i; + int y1, y2; + for (i = tl->begin(); i != tl->end(); ++i) { + track = *i; + QWidget* tw = track->arrangerTrack.tw; + if (tw == 0) { + printf(" invisible Track\n"); + continue; + } + y1 = tw->y(); + y2 = y1 + tw->height(); + if (yp >= y1 && yp < y2) { +// printf(" track <%s> %d - %d\n", track->name().toLatin1().data(), y1, y2); + break; + } + for (iArrangerTrack i = track->subtracks.begin(); i != track->subtracks.end(); ++i) { + at = *i; + if (at->tw == 0) { + printf("----empty subtrack?\n"); + break; + } + y1 = at->tw->y(); + y2 = y1 + at->tw->height(); + if (yp >= y1 && yp < y2) { + return HIT_SUBTRACK; + } + } + } + if (i == tl->end()) { + track = 0; + at = 0; + return HIT_NOTHING; + } + + unsigned x = p.x(); + PartList* pl = track->parts(); + for (iPart ip = pl->begin(); ip != pl->end(); ++ip) { + part = ip->second; + if (x >= part->tick() && x < part->endTick()) { + ppos = mapx(part->tick()); + psize = rmapx(part->lenTick()); +// printf(" part\n"); + return HIT_PART; + } + } + part = 0; + return HIT_TRACK; + } + +//--------------------------------------------------------- +// contextMenu +//--------------------------------------------------------- + +void PartCanvas::contextMenu(const QPoint& pos) + { + QMenu* pop = new QMenu(widget()); + QAction* a; + if (part) { + pop->addAction(getAction("cut", this)); + pop->addAction(getAction("copy", this)); + pop->addSeparator(); + a = pop->addAction(tr("Rename")); + a->setData("rename"); + + QMenu* cp = pop->addMenu(tr("Color")); + + // part color selection + for (int i = 0; i < NUM_PARTCOLORS; ++i) { + a = cp->addAction(partColorNames[i]); + a->setData(QString("color%1").arg(i)); + QPixmap pm(20, 20); + QPainter p(&pm); + p.fillRect(0, 0, 20, 20, config.partColors[i]); + a->setIcon(QIcon(pm)); + } + pop->addAction(getAction("delete", this)); + pop->addAction(getAction("scissor", this)); + pop->addAction(getAction("glue", this)); + a = getAction("declone", this); + a->setEnabled(part->isClone()); + pop->addAction(a); + if (track->type() == Track::MIDI) { + a = pop->addAction(tr("AutoFill...")); + a->setData("autofill"); + } + pop->addSeparator(); + if (track->type() == Track::MIDI) { + MidiTrack* track = (MidiTrack*)part->track(); + if (track->useDrumMap()) { + a = pop->addAction(*edit_drummsIcon, tr("drums")); + a->setData("editdrums"); + } + else { + a = pop->addAction(QIcon(":/xpm/piano.xpm"), tr("pianoroll")); + a->setData("editpiano"); + } + a = pop->addAction(*edit_listIcon, tr("miditracker")); + a->setData("miditracker"); + pop->addAction(getAction("listedit", this)); + } + else { + a = pop->addAction(*waveIcon, tr("wave edit")); + a->setData("waveedit"); + } + + a = pop->exec(mapToGlobal(pos)); + if (a) { + QString cmd = a->data().toString(); + if (cmd == "rename") + renamePart(part); + else if (cmd == "delete") + song->cmdRemovePart(part); + else if (cmd == "scissor") + splitPart(part, startDrag); + else if (cmd == "glue") + song->cmdGluePart(part); + else if (cmd == "cut") + cutPart(part); + else if (cmd == "copy") + copyPart(part); + else if (cmd == "editpiano") + emit startEditor(part, 0); + else if (cmd == "miditracker") + emit startEditor(part, 2); + else if (cmd == "listedit") + emit startEditor(part, 1); + else if (cmd == "drumedit") + emit startEditor(part, 3); + else if (cmd == "waveedit") + emit startEditor(part, 4); + else if (cmd == "declone") + declonePart(part); + else if (cmd == "autofill") { + bool ok; + int ticksM = AL::sigmap.ticksMeasure(part->tick()); + int n = QInputDialog::getInteger(this, + tr("MusE: Get auto fill loop len"), + tr("Measures: "), + part->fillLen() / ticksM, + 0, 16, 1, &ok); + if (ok) { + part->setFillLen(n * ticksM); + } + } + else if (cmd.startsWith("color")) { + int idx = cmd.mid(5).toInt(); + part->setColorIndex(idx); + widget()->update(); + } + else { + printf("unknown action <%s>\n", cmd.toLatin1().data()); + } + } + } + else { + for (int i = 0; i < TOOLS; ++i) { + if ((arrangerTools & (1 << i))==0) + continue; + a = getAction(toolList[i], this); + pop->addAction(a); + a->setCheckable(true); + a->setChecked((1 <exec(mapToGlobal(pos)); + if (a) + muse->setTool(a->data().toString()); + } + } + +//--------------------------------------------------------- +// mousePressEvent +//--------------------------------------------------------- + +void PartCanvas::mousePress(QMouseEvent* me) + { + if (state == S_SUBTRACK) { + ((TLSWidget*)(at->tw))->mouseRelease(); + state = S_NORMAL; + } + + QPoint pos(me->pos().x(), me->pos().y() - rulerHeight); + startDrag = pos; + int hit = searchPart(startDrag); + + if (hit == HIT_SUBTRACK) { + TLSWidget* w = (TLSWidget*)(at->tw); + int y = wpos.y() + pos.y() - w->y(); + w->mousePress(QPoint(pos.x(), y), me); + // propagate drag events to subtrack if left button pressed: + if (me->button() == Qt::LeftButton) + state = S_SUBTRACK; + return; + } + else if ( hit == HIT_NOTHING ) { // nothing here we put up a rubberband + rubberBandStartPos = me->pos(); + if (!rubberBand) + rubberBand = new QRubberBand(QRubberBand::Rectangle, this); + rubberBand->setGeometry(QRect(rubberBandStartPos, QSize())); + rubberBand->show(); + } + + if (button & Qt::RightButton) { + contextMenu(me->pos()); + return; + } + + QRect r1,r2; + QPoint pos2; + int xpos = 0, y = 0, len = 0, h = 0; + + if (hit == HIT_PART) { + h = track->arrangerTrack.tw->height(); + len = rmapx(part->lenTick()); + y = track->arrangerTrack.tw->y() - splitWidth/2; + xpos = mapx(part->tick()); + + r1 = QRect(xpos, y, handleWidth, h); + r2 = QRect(xpos + len - handleWidth, y, handleWidth, h); + pos2 = QPoint(pos.x(), pos.y() + wpos.y()); + } + + switch (_tool) { + case PencilTool: + if (r1.contains(pos2)) + state = S_START_DRAG1; + else if (r2.contains(pos2)) + state = S_START_DRAG2; + else + state = S_START_DRAG5; + ppos = pos2pix(pix2pos(startDrag.x()).downSnaped(raster())); + psize = pos2pix(pix2pos(ppos+1).upSnaped(raster())) - ppos; + startDragTime = QTime::currentTime(); + setCursor(); + break; + case RubberTool: + if (part) + song->cmdRemovePart(part); + break; + case GlueTool: + if (part) + song->cmdGluePart(part); + break; + case CutTool: + if (part) + splitPart(part, pos); + break; + case MuteTool: + if (part) { + part->setMute(!part->mute()); + widget()->update(); + } + break; + default: + if (hit == HIT_PART) { + QRect r3(xpos, y, len, h); + + if (r1.contains(pos2)) { + state = S_START_DRAG1; + } + else if (r2.contains(pos2)) { + state = S_START_DRAG2; + } + else if (r3.contains(pos2)) { + state = S_START_DRAG3; + bool add = keyState & Qt::ShiftModifier; + song->selectPart(part, add); + emit kbdMovementUpdate(track, part); + } + } + if (state == S_NORMAL) { + song->selectPart(0, false); // deselect all parts + emit kbdMovementUpdate(0, 0); // Tell arranger nothing is selected (Keyboard movement) + } + startDragTime = QTime::currentTime(); + setCursor(); + break; + } + } + +//--------------------------------------------------------- +// mouseMove +//--------------------------------------------------------- + +void PartCanvas::mouseMove(QPoint pos) + { + + if(rubberBand) + rubberBand->setGeometry(QRect(rubberBandStartPos, pos).normalized()); + + if (state == S_SUBTRACK) { + TLSWidget* w = (TLSWidget*)(at->tw); + int y = wpos.y() + pos.y() - w->y() - rulerHeight; + w->mouseMove(QPoint(pos.x(), y)); + return; + } + pos -= rCanvasA.topLeft(); + bool update = false; + int x = pos.x(); + int delta = startDrag.x() - x; + int t = startDragTime.msecsTo(QTime::currentTime()); + bool dragActive = (startDrag - pos).manhattanLength() > + QApplication::startDragDistance() + || t > QApplication::startDragTime(); + switch (state) { + case S_START_DRAG1: + if (dragActive) + state = S_DRAG1; + break; + case S_START_DRAG2: + if (dragActive) + state = S_DRAG2; + break; + case S_START_DRAG3: + if (dragActive) + state = S_DRAG3; + break; + case S_START_DRAG5: + if (dragActive) + state = S_DRAG5; + break; + case S_NORMAL: + { + searchPart(pos); + bool found = false; + if (part) { + int h = track->arrangerTrack.tw->height(); + int xpos = mapx(part->tick()); + int len = rmapx(part->lenTick()); + int y = track->arrangerTrack.tw->y(); + QRect r1(xpos, y, handleWidth, h); + QRect r2(xpos + len - handleWidth, y, handleWidth, h); + if (r1.contains(pos) || r2.contains(pos)) + found = true; + } + if (found) { + widget()->setCursor(Qt::SizeHorCursor); + } + else + setCursor(); + } + break; + default: + break; + } + if (!track) + return; + int y = track->arrangerTrack.tw->y(); // - splitWidth/2; + int ph = track->arrangerTrack.tw->height() - 1 - partBorderWidth; + if (state == S_DRAG1) { + // + // drag left edge of part + // + Pos p(pix2pos(ppos - delta)); + p.snap(raster()); + int x1 = pos2pix(p); + int x2 = pos2pix(part->end()); + int size = x2 - x1; + drag.setRect(x1, y, size, ph); + update = true; + } + else if (state == S_DRAG2) { + // + // drag right edge of part + // + int size = psize - delta; + if (size < 10) + size = 10; + int x2 = mapx(AL::sigmap.raster(part->tick() + rmapxDev(size), raster())); + drag.setRect(ppos, y, x2 - ppos, ph); + update = true; + } + else if (state == S_DRAG5) { + // + // draw part with pencil tool + // + int size = psize - delta; + if (size < 10) + size = 10; + int x2 = mapx(AL::sigmap.raster(mapxDev(ppos + size), raster())); + drag.setRect(ppos, y, x2 - ppos, ph); + update = true; + } + else if (state == S_DRAG3) { + // + // drag whole part + // + srcPart = part; + QDrag* d = 0; + if (track->type() == Track::MIDI) + d = new MidiPartDrag(srcPart, this); + else if (track->type() == Track::WAVE) + d = new AudioPartDrag(srcPart, this); + if (d) { + Qt::KeyboardModifiers kb = QApplication::keyboardModifiers(); + Qt::DropActions da = kb ? (Qt::MoveAction | Qt::CopyAction | Qt::LinkAction) : Qt::MoveAction; + song->startUndo(); + _dragOffset = startDrag.x() - rCanvasA.x() - ppos; + if (d->start(da) == Qt::MoveAction) + song->removePart(srcPart); + song->endUndo(0); + update = true; + } + state = S_NORMAL; + } + if (update) + widget()->update(); + } + +//--------------------------------------------------------- +// mouseRelease +//--------------------------------------------------------- + +void PartCanvas::mouseRelease(QMouseEvent* me) + { + + if (rubberBand) + rubberBand->hide(); // TODO robert, nothing more happens for the moment/ + + if (state == S_SUBTRACK) { + ((TLSWidget*)(at->tw))->mouseRelease(); + state = S_NORMAL; + return; + } + + QPoint pos(me->pos()); + int x = pos.x(); + int delta = startDrag.x() - x; + + if (state == S_DRAG1) { + int val = mapxDev(ppos-delta); + int pos = AL::sigmap.raster(val, raster()); + int size = part->tick() + part->lenTick() - pos; + emit partChanged(part, pos, size); + } + else if (state == S_DRAG2) { + int size = psize - delta; + int x1 = part->tick(); + int x2 = AL::sigmap.raster(part->tick() + rmapxDev(size), raster()); + + int step = AL::sigmap.rasterStep(x1, raster()); + if (x2 - x1 < step) + x2 = AL::sigmap.raster(x1 + step, raster()); + emit partChanged(part, x1, x2-x1); + } + else if (state == S_DRAG5) { + if (track && (track->type() == Track::MIDI || track->type() == Track::WAVE)) { + Part* part = track->newPart(); + Pos p1 = pix2pos(drag.x()).snaped(raster()); + Pos p2 = pix2pos(drag.x() + drag.width()).snaped(raster()); + part->setPos(p1); + part->setLenTick(p2.tick() - p1.tick()); + song->cmdAddPart(part); + } + else + widget()->update(); + } + state = S_NORMAL; + setCursor(); + } + +//--------------------------------------------------------- +// mouseDoubleClickEvent +//--------------------------------------------------------- + +void PartCanvas::mouseDoubleClick(QMouseEvent* me) + { + QPoint pos(me->pos().x(), me->pos().y() - rulerHeight); + if (_tool != PointerTool) { +//TD mousePress(pos); + return; + } + bool shift = keyState & Qt::ShiftModifier; + if (searchPart(pos) == HIT_PART) { + if (button == Qt::LeftButton && shift) { + renamePart(part); + } + else if (button == Qt::LeftButton) { + emit doubleClickPart(part); + } + } + // + // double click creates new part between left and + // right mark + + else if (track && track->isMidiTrack()) + emit createLRPart(track); + } + + +//--------------------------------------------------------- +// keyboardNavigate +//--------------------------------------------------------- + +void PartCanvas::keyboardNavigate(QKeyEvent *e) + { + printf("nothing here go away\n"); + } + + +//--------------------------------------------------------- +// setCursor +//--------------------------------------------------------- + +void PartCanvas::setCursor() + { + switch(state) { + case S_START_DRAG1: + case S_START_DRAG2: + case S_DRAG1: + case S_DRAG2: + widget()->setCursor(Qt::SizeHorCursor); + return; + default: + break; + } + TimeCanvas::setCursor(); + } + +//--------------------------------------------------------- +// declonePart +//--------------------------------------------------------- + +void PartCanvas::declonePart(Part* oPart) + { + Track* track = oPart->track(); + Part* nPart = track->newPart(oPart, false); + + EventList* se = oPart->events(); + for (iEvent i = se->begin(); i != se->end(); ++i) { + Event oldEvent = i->second; +// Event ev = oldEvent.clone(); + nPart->addEvent(oldEvent); + } + oPart->deref(); + song->cmdChangePart(oPart, nPart); + } + +//--------------------------------------------------------- +// splitPart +//--------------------------------------------------------- + +void PartCanvas::splitPart(Part* part, const QPoint& p) + { + song->cmdSplitPart(part, pix2pos(p.x()).snaped(raster())); + } + +//--------------------------------------------------------- +// renamePart +//--------------------------------------------------------- + +void PartCanvas::renamePart(Part* part) + { + bool ok; + + QString s = QInputDialog::getText(this, + tr("MusE: Change Part Name"), + tr("PartName:"), + QLineEdit::Normal, + part->name(), + &ok + ); + if (ok && s != part->name()) { + song->startUndo(); + Part* newPart = new Part(*part); + newPart->setName(s); + song->cmdChangePart(part, newPart); + widget()->update(); + } + } + +//--------------------------------------------------------- +// cutPart +//--------------------------------------------------------- + +void PartCanvas::cutPart(Part* part) + { + copyPart(part); + song->cmdRemovePart(part); + } + +//--------------------------------------------------------- +// copyPart +//--------------------------------------------------------- + +void PartCanvas::copyPart(Part* part) + { + QBuffer buffer; + buffer.open(QIODevice::WriteOnly); + AL::Xml xml(&buffer); + part->write(xml); + buffer.close(); + QMimeData* mimeData = new QMimeData; + mimeData->setData(MidiPartDrag::type, buffer.buffer()); + QApplication::clipboard()->setMimeData(mimeData); + } + +//--------------------------------------------------------- +// dragEnter +//--------------------------------------------------------- + +void PartCanvas::dragEnter(QDragEnterEvent* event) + { +#if 0 + QPoint p(event->pos() - rCanvasA.topLeft()); + searchPart(p); + if (!track) { + event->ignore(); + return; + } + int srcIsMidi = -1; + const QMimeData* md = event->mimeData(); + + if (MidiPartDrag::canDecode(md)) + srcIsMidi = 1; + else if (AudioPartDrag::canDecode(md)) + srcIsMidi = 0; + else if (WavUriDrag::canDecode(md)) + srcIsMidi = 0; + + int dstIsMidi = -1; + if (track->type() == Track::MIDI) + dstIsMidi = 1; + else if (track->type() == Track::WAVE) + dstIsMidi = 0; + + if ((srcIsMidi == -1) || (dstIsMidi != srcIsMidi)) { + event->ignore(); + return; + } + Qt::KeyboardModifiers kb = event->keyboardModifiers(); + if (kb == 0 && (Qt::MoveAction & event->possibleActions())) { + event->setDropAction(Qt::MoveAction); + event->accept(); + } + else +#endif + event->acceptProposedAction(); + } + +//--------------------------------------------------------- +// dragMoveEvent +//--------------------------------------------------------- + +void PartCanvas::dragMove(QDragMoveEvent* event) + { + QPoint p(event->pos() - rCanvasA.topLeft()); + searchPart(p); + if (!track) { + event->acceptProposedAction(); + return; + } + Part* srcPart = 0; + QString filename; + + bool srcIsMidi; + const QMimeData* md = event->mimeData(); + if (MidiPartDrag::canDecode(md)) { + MidiPartDrag::decode(md, srcPart); + srcIsMidi = true; + } + else if (AudioPartDrag::canDecode(md)) { + AudioPartDrag::decode(md, srcPart); + srcIsMidi = false; + } + else if (WavUriDrag::canDecode(md)) { + WavUriDrag::decode(md, &filename); + if (state != S_NORMAL) { + state = S_NORMAL; + widget()->update(); + } + if (track->type() == Track::WAVE) + event->acceptProposedAction(); + else + event->ignore(); + return; + } + else { + state = S_NORMAL; + event->ignore(); + return; + } + + int dstIsMidi = -1; + if (track->type() == Track::MIDI) + dstIsMidi = 1; + else if (track->type() == Track::WAVE) + dstIsMidi = 0; + if ((srcIsMidi == -1) || (dstIsMidi != srcIsMidi)) { + if (state != S_NORMAL) { + state = S_NORMAL; + widget()->update(); + } + event->ignore(); + return; + } + Qt::KeyboardModifiers kb = event->keyboardModifiers(); + if (kb == 0 && (Qt::MoveAction & event->possibleActions())) { + event->setDropAction(Qt::MoveAction); + event->accept(); + } + else + event->acceptProposedAction(); + state = S_DRAG4; + ArrangerTrack* at = &(track->arrangerTrack); + + PartCanvas* cw = (PartCanvas*)event->source(); + QRect updateRect(drag); + + Pos pos; + if (cw) + pos = pix2pos(p.x() - cw->dragOffset()).snaped(raster()); + else + pos = pix2pos(p.x()).snaped(raster()); + drag.setRect( + pos2pix(pos), + at->tw->y(), + rmapx(srcPart->lenTick()), + at->tw->height() - 1 - partBorderWidth + ); + delete srcPart; + updateRect |= drag; + updateRect.adjust(-1, -1 + rCanvasA.y(), 1, 1 + rCanvasA.y()); + widget()->update(updateRect); + } + +//--------------------------------------------------------- +// dropEvent +//--------------------------------------------------------- + +void PartCanvas::drop(QDropEvent* event) + { + state = S_NORMAL; + Part* dstPart = 0; + QString filename; + + QPoint pos(event->pos() - rCanvasA.topLeft()); + const QMimeData* md = event->mimeData(); + if (WavUriDrag::canDecode(md)) { + WavUriDrag::decode(md, &filename); + int tick = AL::sigmap.raster(mapxDev(pos.x()), raster()); + Pos pos(tick); + muse->importWaveToTrack(filename, track, pos); + widget()->update(); + return; + } + + bool isMidi = false; + if (MidiPartDrag::canDecode(md)) { + MidiPartDrag::decode(md, dstPart); + isMidi = true; + } + else if (AudioPartDrag::canDecode(md)) + AudioPartDrag::decode(md, dstPart); + + searchPart(pos); + if (!dstPart) + return; + PartCanvas* cw = (PartCanvas*)event->source(); + bool needEndUndo = false; + if (!track) { + if (isMidi) + track = new MidiTrack(); + else + track = new WaveTrack(); + track->setDefaultName(); + if (cw) + song->insertTrack(track, -1); + else { + song->startUndo(); + song->insertTrack(track, -1); + needEndUndo = true; + } + } + else if (isMidi != track->isMidiTrack()) + return; + + dstPart->setTrack(track); + + // + // cw == 0 means that we are dropping to + // another application + + unsigned tick; + if (cw) + tick = AL::sigmap.raster(mapxDev(pos.x() - cw->dragOffset()), raster()); + else + tick = AL::sigmap.raster(mapxDev(pos.x()), raster()); + + dstPart->setTick(tick); + + Qt::DropAction da = event->proposedAction(); + Qt::KeyboardModifiers kb = event->keyboardModifiers(); + if (kb == 0 && (Qt::MoveAction & event->possibleActions())) + da = Qt::MoveAction; + + if ((da == Qt::LinkAction) && (cw == this)) { + delete dstPart->events(); + dstPart->clone(srcPart->events()); + event->setDropAction(Qt::LinkAction); + } + else if (da == Qt::MoveAction) + event->setDropAction(Qt::MoveAction); + else + event->setDropAction(Qt::CopyAction); + event->accept(); + if (cw || needEndUndo) + song->addPart(dstPart); + else + song->cmdAddPart(dstPart); + if (needEndUndo) + song->endUndo(0); + widget()->update(); + } + +//--------------------------------------------------------- +// dragLeave +//--------------------------------------------------------- + +void PartCanvas::dragLeave(QDragLeaveEvent*) + { + if (state == S_DRAG4) { + state = S_NORMAL; + widget()->update(); + } + } + diff --git a/muse/muse/canvas.h b/muse/muse/canvas.h new file mode 100644 index 00000000..911936c2 --- /dev/null +++ b/muse/muse/canvas.h @@ -0,0 +1,124 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __CANVAS_H__ +#define __CANVAS_H__ + +#include "awl/tcanvas.h" +#include "widgets/tools.h" + +class CanvasWidget; +class Part; +class Track; +class ArrangerTrack; + +static const int HANDLE1 = 6; +static const int HANDLE2 = 3; + +//--------------------------------------------------------- +// PartCanvas +//--------------------------------------------------------- + +class PartCanvas : public TimeCanvas { + Q_OBJECT + + // DRAG1 drag part head + // DRAG2 drag part tail + // DRAG3 drag whole part + // DRAG4 Drag&Drop drag + // DRAG5 draw part with pencil tool + + enum { S_NORMAL, S_START_DRAG1, S_START_DRAG2, S_START_DRAG3, + S_DRAG1, S_DRAG2, S_DRAG3, + S_DRAG4, + S_START_DRAG5, S_DRAG5, // draw new Part + S_SUBTRACK + }; + int state; + QPoint startDrag; + int _dragOffset; + QRect drag; + QTime startDragTime; + unsigned ppos, psize; + + // values set by searchPart(): + Track* track; + Part* part; + ArrangerTrack* at; + + Part* srcPart; // src part of a drag/drop operation + + bool _drawBackground; + int selected; + int lselected; // in local coordinates + int starty; + int dragy; + + virtual void paint(QPainter&, QRect); + void drawWavePart(QPainter& p, Part* part, int, int, int, int); + void drawMidiPart(QPainter& p, Part* mp, int, int, int, int); + virtual void mousePress(QMouseEvent*); + virtual void mouseMove(QPoint); + virtual void mouseRelease(QMouseEvent*); + virtual void mouseDoubleClick(QMouseEvent*); + + virtual void dragEnter(QDragEnterEvent*); + virtual void drop(QDropEvent*); + virtual void dragMove(QDragMoveEvent*); + virtual void dragLeave(QDragLeaveEvent*); + + virtual void keyboardNavigate(QKeyEvent *e); + + + int searchPart(const QPoint& p); + + void declonePart(Part* part); + void renamePart(Part*); + void splitPart(Part*, const QPoint&); + void cutPart(Part*); + void copyPart(Part*); + + void setCursor(); + int dragOffset() const { return _dragOffset; } + void drawHandle(QPainter& p, int x, int y) { + p.fillRect(x-HANDLE2, y-HANDLE2, HANDLE1, HANDLE1, x == lselected ? Qt::red : Qt::yellow); + } + void contextMenu(const QPoint&); + + QRubberBand *rubberBand; + QPoint rubberBandStartPos; + + private slots: + void markerChanged(int); + + signals: + void kbdMovementUpdate(Track* t, Part* p); + void startEditor(Part*, int); + void createLRPart(Track*); + void partChanged(Part*, unsigned, unsigned); + void doubleClickPart(Part*); + + public: + PartCanvas(); + void setDrawBackground(bool val) { _drawBackground = val; } + }; + +#endif + diff --git a/muse/muse/configtrack.cpp b/muse/muse/configtrack.cpp new file mode 100644 index 00000000..a8fee6a3 --- /dev/null +++ b/muse/muse/configtrack.cpp @@ -0,0 +1,265 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "configtrack.h" +#include "trelement.h" +#include "arranger.h" + +//--------------------------------------------------------- +// ConfigTrackList +//--------------------------------------------------------- + +ConfigTrackList::ConfigTrackList(QWidget* parent) + : QDialog(parent) + { + setupUi(this); + // does not work: + configuredList->setSelectionMode(QAbstractItemView::SingleSelection); + availableList->setSelectionMode(QAbstractItemView::SingleSelection); + + up->setEnabled(false); + down->setEnabled(false); + addItem->setEnabled(false); + removeItem->setEnabled(false); + dirty = false; + curType = 0; + init(); + + connect(trackType, SIGNAL(activated(int)), SLOT(trackTypeChanged(int))); + connect(availableList, SIGNAL(itemSelectionChanged()), SLOT(availableSelected())); + connect(configuredList, SIGNAL(itemSelectionChanged()), SLOT(configuredSelected())); + connect(up, SIGNAL(clicked()), SLOT(upClicked())); + connect(down, SIGNAL(clicked()), SLOT(downClicked())); + connect(addItem, SIGNAL(clicked()), SLOT(addItemClicked())); + connect(removeItem, SIGNAL(clicked()), SLOT(removeItemClicked())); + } + +//--------------------------------------------------------- +// init +//--------------------------------------------------------- + +void ConfigTrackList::init() + { + trackType->clear(); + for (int tt = 0; tt < Track::TRACK_TYPES; ++tt) { + list[tt] = glist[tt]; + trackType->addItem(Track::_clname[tt]); + } + trackTypeChanged(curType); + } + +//--------------------------------------------------------- +// done +//--------------------------------------------------------- + +void ConfigTrackList::done(int code) + { + if (code) { + // OK pressed + if (dirty) + saveTrackType(); + for (int tt = 0; tt < Track::TRACK_TYPES; ++tt) + glist[tt] = list[tt]; + emit trackConfigChanged(); + } + else { + dirty = false; + init(); + } + QDialog::done(code); + } + +//--------------------------------------------------------- +// saveTrackType +//--------------------------------------------------------- + +void ConfigTrackList::saveTrackType() + { + dirty = false; + list[curType].clear(); + int gn = 0; + TrElementList group; + int n = configuredList->count(); + for (int i = 0; i < n; ++i) { + QString s = configuredList->item(i)->text(); + int k; + for (k = 0; k < nTrElements; ++k) + if (trElements[k].name == s) + break; + if (trElements[k].grp != gn) { + list[curType].push_back(group); + group.clear(); + gn = trElements[k].grp; + } + group.push_back(&trElements[k]); + } + if (!group.empty()) + list[curType].push_back(group); + } + +//--------------------------------------------------------- +// trackTypeChanged +//--------------------------------------------------------- + +void ConfigTrackList::trackTypeChanged(int type) + { + curType = type; + if (dirty) + saveTrackType(); + + configuredList->clear(); + TrGroupList& gl = list[type]; + for (iTrGroup i = gl.begin(); i != gl.end(); ++i) { + for (iTrElement k = i->begin(); k != i->end(); ++k) + configuredList->addItem((*k)->name); + } + + availableList->clear(); + for (int i = 0; i < nTrElements; ++i) { + QString name(trElements[i].name); + bool f = false; + + // is gui element available for this track type? + + for (int i = 0; i < nTrElements; ++i) { + const TrElement& el = trElements[i]; + if (el.name == name) { + if (el.trackMask & (1 << type)) { + f = true; + break; + } + } + } + if (!f) + continue; + + // is gui element already configured? + + for (iTrGroup i = gl.begin(); i != gl.end(); ++i) { + for (iTrElement k = i->begin(); k != i->end(); ++k) { + if (name == (*k)->name) { + f = false; + break; + } + } + if (!f) + break; + } + if (f) { + availableList->addItem(name); + } + } + } + +//--------------------------------------------------------- +// configuredSelected +//--------------------------------------------------------- + +void ConfigTrackList::configuredSelected() + { + QListWidgetItem* item = configuredList->selectedItems().at(0); + up->setEnabled(item != 0); + down->setEnabled(item != 0); + removeItem->setEnabled(item != 0); + } + +//--------------------------------------------------------- +// availableSelected +//--------------------------------------------------------- + +void ConfigTrackList::availableSelected() + { + QListWidgetItem* item = availableList->selectedItems().at(0); + addItem->setEnabled(item != 0); + } + +//--------------------------------------------------------- +// upClicked +//--------------------------------------------------------- + +void ConfigTrackList::upClicked() + { + QListWidgetItem* item = configuredList->selectedItems().at(0); + int n = configuredList->row(item); + if (n <= 0) + return; + QString s = item->text(); + delete item; + configuredList->insertItem(n-1, s); + configuredList->setItemSelected(configuredList->item(n-1), true); + dirty = true; + } + +//--------------------------------------------------------- +// downClicked +//--------------------------------------------------------- + +void ConfigTrackList::downClicked() + { + QListWidgetItem* item = configuredList->selectedItems().at(0); + int n = configuredList->row(item); + if (n >= int(configuredList->count()-1)) + return; + QString s = item->text(); + + delete item; + configuredList->insertItem(n+1, s); + configuredList->setItemSelected(configuredList->item(n+1), true); + dirty = true; + } + +//--------------------------------------------------------- +// addItemClicked +//--------------------------------------------------------- + +void ConfigTrackList::addItemClicked() + { + QListWidgetItem* item = availableList->selectedItems().at(0); + if (item == 0) + return; + QString s = item->text(); + delete item; + configuredList->addItem(s); + configuredList->setItemSelected(configuredList->item(configuredList->count()-1), true); + QListWidgetItem* ci = availableList->currentItem(); + if (ci) + availableList->setItemSelected(ci, true); + dirty = true; + } + +//--------------------------------------------------------- +// removeItemClicked +//--------------------------------------------------------- + +void ConfigTrackList::removeItemClicked() + { + QListWidgetItem* item = configuredList->selectedItems().at(0); + if (item == 0) + return; + QString s = item->text(); + delete item; + availableList->addItem(s); + availableList->setItemSelected(availableList->item(availableList->count()-1), true); + QListWidgetItem* ci = configuredList->item(configuredList->currentRow()); + if (ci) + configuredList->setItemSelected(ci, true); + dirty = true; + } + diff --git a/muse/muse/configtrack.h b/muse/muse/configtrack.h new file mode 100644 index 00000000..47dd0f4a --- /dev/null +++ b/muse/muse/configtrack.h @@ -0,0 +1,61 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __CONFIG_TRACK_H__ +#define __CONFIG_TRACK_H__ + +#include "ui_configtrack.h" +#include "track.h" +#include "trelement.h" + +struct TrElement; +class TrGroupList; + +//--------------------------------------------------------- +// ConfigTrackList +//--------------------------------------------------------- + +class ConfigTrackList : public QDialog, Ui::ConfigTrackListBase { + Q_OBJECT + + TrGroupList list[Track::TRACK_TYPES]; + void init(); + bool dirty; + void saveTrackType(); + int curType; + + private slots: + void trackTypeChanged(int); + void availableSelected(); + void configuredSelected(); + void upClicked(); + void downClicked(); + void addItemClicked(); + void removeItemClicked(); + virtual void done(int); + + signals: + void trackConfigChanged(); + + public: + ConfigTrackList(QWidget*); + }; + +#endif diff --git a/muse/muse/configtrack.ui b/muse/muse/configtrack.ui new file mode 100644 index 00000000..350b405a --- /dev/null +++ b/muse/muse/configtrack.ui @@ -0,0 +1,299 @@ + + + + + ConfigTrackListBase + + + + 0 + 0 + 545 + 352 + + + + MusE: Config Track List + + + true + + + + 11 + + + 6 + + + + + 0 + + + 6 + + + + + Track Type: + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + + 0 + + + 6 + + + + + 0 + + + 6 + + + + + Available Items: + + + + + + + QAbstractItemView::SelectRows + + + 0 + + + + + + + + + 0 + + + 6 + + + + + Add + + + + + + + Remove + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 40 + + + + + + + + Up + + + + + + + Down + + + + + + + + + 0 + + + 6 + + + + + Configured Items + + + + + + + QAbstractItemView::SelectRows + + + + + + + + + + + 0 + + + 6 + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + + 0 + + + 6 + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 20 + 20 + + + + + + + + &OK + + + + + + true + + + true + + + + + + + &Cancel + + + + + + true + + + + + + + + + qPixmapFromMimeSource + + + + ok + clicked() + ConfigTrackListBase + accept() + + + 393 + 321 + + + 259 + 326 + + + + + cancel + clicked() + ConfigTrackListBase + reject() + + + 484 + 327 + + + 437 + 283 + + + + + diff --git a/muse/muse/importmidi.cpp b/muse/muse/importmidi.cpp index c995ed67..0bd33df8 100644 --- a/muse/muse/importmidi.cpp +++ b/muse/muse/importmidi.cpp @@ -36,7 +36,7 @@ #include "templatedialog.h" #include "audio.h" #include "mixer.h" -#include "arranger/arranger.h" +#include "arranger.h" #include "midictrl.h" #include "midiinport.h" #include "midioutport.h" diff --git a/muse/muse/jack.cpp b/muse/muse/jack.cpp index ff32846e..bc372357 100644 --- a/muse/muse/jack.cpp +++ b/muse/muse/jack.cpp @@ -53,25 +53,6 @@ static void jack_thread_init (void* /*data*/) if (loadVST) fst_adopt_thread(); #endif - int policy; - if ( (policy = sched_getscheduler (0)) < 0) { - printf("cannot get current client scheduler for JACK thread: %s!\n", strerror(errno)); - } - else { - if (policy != SCHED_FIFO) - printf("JACK thread %d _NOT_ running SCHED_FIFO\n", getpid()); - else if (debugMsg) { - struct sched_param rt_param; - memset(&rt_param, 0, sizeof(sched_param)); - int type; - int rv = pthread_getschedparam(pthread_self(), &type, &rt_param); - if (rv == -1) - perror("get scheduler parameter"); - printf("JACK thread running SCHED_FIFO priority %d\n", - rt_param.sched_priority); - } - } - } //--------------------------------------------------------- @@ -816,10 +797,10 @@ void JackAudio::putEvent(Port port, const MidiEvent& e) } void* pb = jack_port_get_buffer(port.jackPort(), segmentSize); int ft = e.time() - _frameCounter; - if (ft < 0 || ft >= (int)segmentSize) { + if (ft < 0) + ft = 0; + if (ft >= (int)segmentSize) { printf("JackAudio::putEvent: time out of range %d(seg=%d)\n", ft, segmentSize); - if (ft < 0) - ft = 0; if (ft > (int)segmentSize) ft = segmentSize - 1; } diff --git a/muse/muse/midiportinfo.ui b/muse/muse/midiportinfo.ui new file mode 100644 index 00000000..ad8ae201 --- /dev/null +++ b/muse/muse/midiportinfo.ui @@ -0,0 +1,92 @@ + + MidiPortInfoBase + + + + 0 + 0 + 142 + 96 + + + + + 0 + 0 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 16777215 + 24 + + + + Midi Instrument + + + + + + + + 16777215 + 24 + + + + 127 + + + 127 + + + + + + + + 16777215 + 24 + + + + Device-Id: + + + + + + + + diff --git a/muse/muse/miditrackinfo.ui b/muse/muse/miditrackinfo.ui new file mode 100644 index 00000000..c1624188 --- /dev/null +++ b/muse/muse/miditrackinfo.ui @@ -0,0 +1,292 @@ + + MidiTrackInfoBase + + + + 0 + 0 + 135 + 165 + + + + + 0 + 0 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 16777215 + 24 + + + + Transp. + + + + + + + + 0 + 0 + + + + + 16777215 + 24 + + + + Pitch Transpose + + + -127 + + + 127 + + + + + + + + 0 + 0 + + + + + 16777215 + 24 + + + + Delay + + + + + + + + 0 + 0 + + + + + 16777215 + 24 + + + + Track Delay (ticks) + + + -1000 + + + 1000 + + + + + + + + 0 + 0 + + + + + 16777215 + 24 + + + + Length + + + + + + + + 0 + 0 + + + + + 16777215 + 24 + + + + Modify Note Length + + + % + + + 25 + + + 200 + + + + + + + + 0 + 0 + + + + + 16777215 + 24 + + + + Velocity + + + + + + + + 0 + 0 + + + + + 16777215 + 24 + + + + Modify Note Velocity + + + -127 + + + 127 + + + + + + + + 0 + 0 + + + + + 16777215 + 24 + + + + Compr. + + + + + + + + 0 + 0 + + + + + 16777215 + 24 + + + + Compress Note Velocity + + + % + + + 25 + + + 200 + + + + + + + + 0 + 0 + + + + + 16777215 + 24 + + + + Instrument Patch + + + ??? + + + + + + + + diff --git a/muse/muse/mstrip.cpp b/muse/muse/mstrip.cpp index d4c48f5e..64b8132c 100644 --- a/muse/muse/mstrip.cpp +++ b/muse/muse/mstrip.cpp @@ -3,7 +3,7 @@ // Linux Music Editor // $Id:$ // -// Copyright (C) 2002-2006 by Werner Schweer and others +// Copyright (C) 2002-2008 by Werner Schweer and others // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2. @@ -75,7 +75,7 @@ void addMidiTracks(QMenu* menu, Track* track, int channel, bool input) // can only be added to input route lists //--------------------------------------------------------- -void addMidiInPorts(QMenu* menu, Track* dtrack, int channel) +void Strip::addMidiInPorts(QMenu* menu, Track* dtrack, int channel) { RouteList* rl = dtrack->inRoutes(); RouteNode dst(dtrack, channel, RouteNode::TRACK); @@ -84,8 +84,6 @@ void addMidiInPorts(QMenu* menu, Track* dtrack, int channel) for (iMidiInPort i = tl->begin();i != tl->end(); ++i) { MidiInPort* track = *i; QMenu* m = menu->addMenu(track->name()); - m->setSeparatorsCollapsible(false); - m->addSeparator()->setText(QT_TR_NOOP("Channels")); for (int ch = 0; ch < MIDI_CHANNELS; ++ch) { QAction* a = m->addAction(QString("Channel %1").arg(ch+1)); a->setCheckable(true); @@ -102,7 +100,7 @@ void addMidiInPorts(QMenu* menu, Track* dtrack, int channel) // can only be added to output route lists //--------------------------------------------------------- -static void addMidiOutPorts(QMenu* menu, Track* strack, int channel) +void Strip::addMidiOutPorts(QMenu* menu, Track* strack, int channel) { RouteList* rl = strack->outRoutes(); RouteNode src(strack, channel, RouteNode::TRACK); @@ -111,8 +109,6 @@ static void addMidiOutPorts(QMenu* menu, Track* strack, int channel) for (iMidiOutPort i = tl->begin();i != tl->end(); ++i) { MidiOutPort* op = *i; QMenu* m = menu->addMenu(op->name()); - m->setSeparatorsCollapsible(false); - m->addSeparator()->setText(QT_TR_NOOP("Channels")); for (int ch = 0; ch < MIDI_CHANNELS; ++ch) { QAction* a = m->addAction(QString("Channel %1").arg(ch+1)); a->setCheckable(true); @@ -138,8 +134,6 @@ static void addSyntiPorts(QMenu* menu, Track* strack, int channel) for (iSynthI i = sl->begin(); i != sl->end(); ++i) { SynthI* sy = *i; QMenu* m = menu->addMenu(sy->name()); - m->setSeparatorsCollapsible(false); - m->addSeparator()->setText(QT_TR_NOOP("Channels")); for (int ch = 0; ch < MIDI_CHANNELS; ++ch) { QAction* a = m->addAction(QString("Channel %1").arg(ch+1)); a->setCheckable(true); @@ -227,7 +221,6 @@ MidiStrip::MidiStrip(Mixer* m, MidiTrack* t, bool align) sl = new Awl::MidiVolEntry(this); sl->setId(CTRL_VOLUME); -// sl->setFont(config.fonts[1]); sl->setFixedHeight(entrySize.height()); connect(slider, SIGNAL(valueChanged(double,int)), SLOT(ctrlChanged(double, int))); @@ -287,13 +280,11 @@ MidiStrip::MidiStrip(Mixer* m, MidiTrack* t, bool align) iR = newInRouteButton(); grid->addWidget(iR, 14, 0); connect(iR->menu(), SIGNAL(aboutToShow()), SLOT(iRouteShow())); - connect(iR->menu(), SIGNAL(aboutToHide()), SLOT(iRouteHide())); connect(iR->menu(), SIGNAL(triggered(QAction*)), song, SLOT(routeChanged(QAction*))); oR = newOutRouteButton(); grid->addWidget(oR, 14, 1); connect(oR->menu(), SIGNAL(aboutToShow()), SLOT(oRouteShow())); - connect(oR->menu(), SIGNAL(aboutToHide()), SLOT(oRouteHide())); connect(oR->menu(), SIGNAL(triggered(QAction*)), song, SLOT(routeChanged(QAction*))); connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int))); @@ -310,34 +301,6 @@ MidiStrip::MidiStrip(Mixer* m, MidiTrack* t, bool align) controllerChanged(CTRL_CHORUS_SEND); } -//--------------------------------------------------------- -// iRouteHide -//--------------------------------------------------------- - -void MidiStrip::iRouteHide() - { - // dont leave the menu if SHIFT is pressed; this allows - // for fast selecting of more than one input source - // - if (qApp->keyboardModifiers() & Qt::ShiftModifier) { - iR->menu()->show(); - } - } - -//--------------------------------------------------------- -// oRouteHide -//--------------------------------------------------------- - -void MidiStrip::oRouteHide() - { - // dont leave the menu if SHIFT is pressed; this allows - // for fast selecting of more than one input source - // - if (qApp->keyboardModifiers() & Qt::ShiftModifier) { - oR->menu()->show(); - } - } - //--------------------------------------------------------- // songChanged //--------------------------------------------------------- @@ -508,7 +471,6 @@ void MidiStrip::iRouteShow() { QMenu* pup = iR->menu(); pup->clear(); - pup->addSeparator()->setText(tr("Tracks")); addMidiInPorts(pup, track, -1); // add midi inputs to menu } @@ -520,7 +482,6 @@ void MidiStrip::oRouteShow() { QMenu* pup = oR->menu(); pup->clear(); - pup->addSeparator()->setText(tr("OutputPorts")); addMidiOutPorts(pup, track, -1); addSyntiPorts(pup, track, -1); } @@ -783,7 +744,6 @@ void MidiOutPortStrip::iRouteShow() { QMenu* pup = iR->menu(); pup->clear(); - pup->addSeparator()->setText(tr("MidiChannel")); for (int ch = 0; ch < MIDI_CHANNELS; ++ch) { QMenu* m = pup->addMenu(QString("Channel %1").arg(ch+1)); @@ -1001,7 +961,6 @@ void MidiInPortStrip::oRouteShow() { QMenu* pup = oR->menu(); pup->clear(); - pup->addSeparator()->setText(tr("MidiChannel")); for (int ch = 0; ch < MIDI_CHANNELS; ++ch) { QMenu* m = pup->addMenu(QString("Channel %1").arg(ch+1)); @@ -1230,33 +1189,7 @@ void MidiSyntiStrip::oRouteShow() { QMenu* pup = oR->menu(); pup->clear(); - pup->addSeparator()->setText(tr("OutputPorts")); - - MidiOutPortList* mpl = song->midiOutPorts(); - int pn = 0; - for (iMidiOutPort i = mpl->begin(); i != mpl->end(); ++i, ++pn) { - MidiOutPort* op = *i; - QMenu* m = pup->addMenu(op->name()); - m->addSeparator()->setText(tr("Channel")); -#if 0 //TODO - for (int channel = 0; channel < MIDI_CHANNELS; ++channel) { - QString s; - s.setNum(channel+1); - QAction* action = m->addAction(s); - MidiChannel* mc = op->channel(channel); - Route r(mc, -1, Route::TRACK); - action->setData(QVariant::fromValue(r)); - action->setCheckable(true); - - for (iRoute ir = orl->begin(); ir != orl->end(); ++ir) { - if (r == *ir) { - action->setChecked(true); - break; - } - } - } -#endif - } + addMidiOutPorts(pup, track, -1); } //--------------------------------------------------------- @@ -1268,7 +1201,6 @@ void MidiSyntiStrip::iRouteShow() QMenu* pup = oR->menu(); pup->clear(); - pup->addSeparator()->setText(tr("Input Ports")); MidiOutPort* t = (MidiOutPort*)track; for (int ch = 0; ch < MIDI_CHANNELS; ++ch) { diff --git a/muse/muse/mstrip.h b/muse/muse/mstrip.h index 4c3269de..058884db 100644 --- a/muse/muse/mstrip.h +++ b/muse/muse/mstrip.h @@ -74,11 +74,10 @@ class MidiStrip : public Strip { void autoReadToggled(bool); void autoWriteToggled(bool); void iRouteShow(); - void iRouteHide(); void oRouteShow(); - void oRouteHide(); void recordToggled(bool); void monitorToggled(bool); + QMenu* sendMenu() const { return static_cast(sender()); } public slots: virtual void songChanged(int); diff --git a/muse/muse/muse.cpp b/muse/muse/muse.cpp index 52767384..01f0d1c4 100644 --- a/muse/muse/muse.cpp +++ b/muse/muse/muse.cpp @@ -23,7 +23,7 @@ #include "muse.h" #include "transport.h" #include "widgets/bigtime.h" -#include "arranger/arranger.h" +#include "arranger.h" #include "midiedit/pianoroll.h" #include "al/al.h" #include "al/xml.h" diff --git a/muse/muse/partdrag.cpp b/muse/muse/partdrag.cpp new file mode 100644 index 00000000..c47d3c11 --- /dev/null +++ b/muse/muse/partdrag.cpp @@ -0,0 +1,199 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "partdrag.h" +#include "al/xml.h" +#include "part.h" + +const char MidiPartDrag::type[] = "application/muse/part/midi"; +const char AudioPartDrag::type[] = "application/muse/part/audio"; +const char WavUriDrag::type[] = "text/uri-list"; + +//--------------------------------------------------------- +// MidiPartDrag +//--------------------------------------------------------- + +MidiPartDrag::MidiPartDrag(Part* part, QWidget* src) + : QDrag(src) + { + QBuffer buffer; + buffer.open(QIODevice::WriteOnly); + AL::Xml xml(&buffer); + part->write(xml); + buffer.close(); + QMimeData* mimeData = new QMimeData; + mimeData->setData(type, buffer.buffer()); + setMimeData(mimeData); + } + +//--------------------------------------------------------- +// canDecode +//--------------------------------------------------------- + +bool MidiPartDrag::canDecode(const QMimeData* s) + { + return s->hasFormat(type); + } + +//--------------------------------------------------------- +// decode +//--------------------------------------------------------- + +bool MidiPartDrag::decode(const QMimeData* s, Part*& p) + { + p = 0; + QDomDocument doc; + int line, column; + QString err; + if (!doc.setContent(s->data(type), false, &err, &line, &column)) { + QString col, ln, error; + col.setNum(column); + ln.setNum(line); + error = err + "\n at line: " + ln + " col: " + col; + printf("error parsing part: %s\n", error.toLatin1().data()); + return false; + } + for (QDomNode node = doc.documentElement(); !node.isNull(); node = node.nextSibling()) { + QDomElement e = node.toElement(); + if (e.isNull()) + continue; + if (e.tagName() == "part") { + p = new Part(0); + p->ref(); + p->read(node, true); + } + else + printf("MusE: %s not supported\n", e.tagName().toLatin1().data()); + } + return (p != 0); + } + +//--------------------------------------------------------- +// PartDrag +// does only transfer reference to part, this does +// not allow for transfers between different apps +// TODO: transfer content (xml representation) +//--------------------------------------------------------- + +AudioPartDrag::AudioPartDrag(Part* part, QWidget* src) + : QDrag(src) + { + QBuffer buffer; + buffer.open(QIODevice::WriteOnly); + Xml xml(&buffer); + part->write(xml); + buffer.close(); + + QMimeData* mimeData = new QMimeData; + mimeData->setData(type, buffer.buffer()); + setMimeData(mimeData); + } + +//--------------------------------------------------------- +// canDecode +//--------------------------------------------------------- + +bool AudioPartDrag::canDecode(const QMimeData* s) + { + return s->hasFormat(type); + } + +//--------------------------------------------------------- +// decode +//--------------------------------------------------------- + +bool AudioPartDrag::decode(const QMimeData* s, Part*& p) + { + p = 0; + QDomDocument doc; + int line, column; + QString err; + if (!doc.setContent(s->data(type), false, &err, &line, &column)) { + QString col, ln, error; + col.setNum(column); + ln.setNum(line); + error = err + "\n at line: " + ln + " col: " + col; + printf("error parsing part: %s\n", error.toLatin1().data()); + return false; + } + for (QDomNode node = doc.documentElement(); !node.isNull(); node = node.nextSibling()) { + QDomElement e = node.toElement(); + if (e.isNull()) + continue; + if (e.tagName() == "part") { + p = new Part(0); + p->ref(); + p->read(node, false); + } + else + printf("MusE: %s not supported\n", e.tagName().toLatin1().data()); + } + return (p != 0); + } + +//--------------------------------------------------------- +// WavUriDrag +//--------------------------------------------------------- + +WavUriDrag::WavUriDrag(const QString& s, QWidget* src) + : QDrag(src) + { + QByteArray a(s.toAscii()); + QMimeData* mimeData = new QMimeData; + mimeData->setData(type, a); + setMimeData(mimeData); + } + +//--------------------------------------------------------- +// canDecode +//--------------------------------------------------------- + +bool WavUriDrag::canDecode(const QMimeData* s) + { + if (!s->hasFormat(type)) + return false; + QByteArray data = s->data(type); + QUrl url(data); + if (url.scheme() != "file") + return false; + QFileInfo fi(url.toLocalFile().trimmed()); + if (!fi.exists()) { + printf("drag file <%s> does not exist\n", fi.filePath().toLatin1().data()); + return false; + } + if (fi.suffix() != "wav") { + printf("drag file <%s> has no wav suffix\n", fi.filePath().toLatin1().data()); + return false; + } + return true; + } + +//--------------------------------------------------------- +// decode +//--------------------------------------------------------- + +bool WavUriDrag::decode(const QMimeData* s, QString* uri) + { + QByteArray data = s->data(type); + QUrl url(data); + *uri = url.toLocalFile().trimmed(); + return true; + } + diff --git a/muse/muse/partdrag.h b/muse/muse/partdrag.h new file mode 100644 index 00000000..d8c2e978 --- /dev/null +++ b/muse/muse/partdrag.h @@ -0,0 +1,69 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __PARTDRAG_H__ +#define __PARTDRAG_H__ + +class Part; + +//--------------------------------------------------------- +// MidiPartDrag +//--------------------------------------------------------- + +class MidiPartDrag : public QDrag { + Q_OBJECT + + public: + static const char type[]; + MidiPartDrag(Part*, QWidget* src); + static bool canDecode(const QMimeData*); + static bool decode(const QMimeData* s, Part*& p); + }; + +//--------------------------------------------------------- +// AudioPartDrag +//--------------------------------------------------------- + +class AudioPartDrag : public QDrag { + Q_OBJECT + + public: + static const char type[]; + AudioPartDrag(Part*, QWidget* src); + static bool canDecode(const QMimeData*); + static bool decode(const QMimeData* s, Part*& p); + }; + +//--------------------------------------------------------- +// WavUriDrag +//--------------------------------------------------------- + +class WavUriDrag : public QDrag { + Q_OBJECT + + public: + static const char type[]; + WavUriDrag(const QString&, QWidget* src); + static bool canDecode(const QMimeData*); + static bool decode(const QMimeData* s, QString* p); + }; + +#endif + diff --git a/muse/muse/preferences.cpp b/muse/muse/preferences.cpp index 6b7580d5..022a24da 100644 --- a/muse/muse/preferences.cpp +++ b/muse/muse/preferences.cpp @@ -24,7 +24,7 @@ #include "muse.h" #include "song.h" #include "event.h" -#include "arranger/arranger.h" +#include "arranger.h" #include "widgets/filedialog.h" #include "waveedit/waveedit.h" #include "globals.h" diff --git a/muse/muse/selectfilter.h b/muse/muse/selectfilter.h new file mode 100644 index 00000000..a28e6947 --- /dev/null +++ b/muse/muse/selectfilter.h @@ -0,0 +1,51 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __SELECTFILTER_H__ +#define __SELECTFILTER_H__ + +//--------------------------------------------------------- +// SelectFilter +//--------------------------------------------------------- + +class SelectFilter :public QObject + { + QWidget* w; + Track* t; + + protected: + bool eventFilter(QObject*, QEvent* ev) + { + if (ev->type() == QEvent::MouseButtonPress) { + w->setFocus(); + song->selectTrack(t); + } + return false; + } + public: + SelectFilter(QObject* parent, QWidget* widget, Track* track) + : QObject(parent) { + w = widget; + t = track; + } + }; + +#endif + diff --git a/muse/muse/seqmsg.cpp b/muse/muse/seqmsg.cpp index adf2a66e..cbd0d0dd 100644 --- a/muse/muse/seqmsg.cpp +++ b/muse/muse/seqmsg.cpp @@ -27,7 +27,7 @@ #include "audio.h" #include "audiodev.h" #include "audio.h" -#include "arranger/arranger.h" +#include "arranger.h" #include "plugin.h" #include "midi.h" #include "midictrl.h" diff --git a/muse/muse/song.cpp b/muse/muse/song.cpp index 79e1f563..a1f3bff0 100644 --- a/muse/muse/song.cpp +++ b/muse/muse/song.cpp @@ -1103,8 +1103,12 @@ void Song::seqSignal(int fd) strerror(errno)); return; } + bool graphChangedCalled = false; + bool seekDone = false; + +// printf("seqSignal %d\n", n); for (int i = 0; i < n; ++i) { -// printf("seqSignal to gui:<%c>\n", buffer[i]); +// printf(" seqSignal to gui:<%c>\n", buffer[i]); switch(buffer[i]) { case MSG_STOP: stopRolling(); @@ -1116,9 +1120,12 @@ void Song::seqSignal(int fd) setRecord(true); break; case MSG_SEEK: - setPos(0, audio->seqTime()->curTickPos, true, false, !seekInProgress); - seekInProgress = false; - beat(); // update controller guis + if (!seekDone) { + seekDone = true; + setPos(0, audio->seqTime()->curTickPos, true, false, !seekInProgress); + seekInProgress = false; + beat(); // update controller guis + } break; case MSG_JACK_SHUTDOWN: restartJack(); @@ -1152,7 +1159,11 @@ void Song::seqSignal(int fd) break; case MSG_GRAPH_CHANGED: - audioDriver->graphChanged(); + if (!graphChangedCalled) { + printf(" graph changed\n"); + graphChangedCalled = true; + audioDriver->graphChanged(); + } break; default: diff --git a/muse/muse/songfile.cpp b/muse/muse/songfile.cpp index 4f701bae..ff89e41e 100644 --- a/muse/muse/songfile.cpp +++ b/muse/muse/songfile.cpp @@ -20,7 +20,7 @@ #include "muse.h" #include "song.h" -#include "arranger/arranger.h" +#include "arranger.h" #include "al/al.h" #include "al/xml.h" #include "midiedit/drummap.h" diff --git a/muse/muse/strip.h b/muse/muse/strip.h index f9bc06ea..1e5f7bd4 100644 --- a/muse/muse/strip.h +++ b/muse/muse/strip.h @@ -29,7 +29,6 @@ class Meter; class SimpleButton; class Mixer; -// static const QSize buttonSize(STRIP_WIDTH/2-2, BUTTON_HEIGHT); static const QSize entrySize(STRIP_WIDTH/2-2, ENTRY_HEIGHT); //--------------------------------------------------------- @@ -55,6 +54,8 @@ class Strip : public QFrame { void recordToggled(bool); void addAutomationButtons(int row); + void addMidiInPorts(QMenu* menu, Track* dtrack, int channel); + void addMidiOutPorts(QMenu* menu, Track* strack, int channel); public slots: void resetPeaks(); diff --git a/muse/muse/tllineedit.cpp b/muse/muse/tllineedit.cpp new file mode 100644 index 00000000..0581b858 --- /dev/null +++ b/muse/muse/tllineedit.cpp @@ -0,0 +1,70 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "tllineedit.h" + +//--------------------------------------------------------- +// TLLineEdit +//--------------------------------------------------------- + +TLLineEdit::TLLineEdit(const QString& contents, QWidget* parent) + : QLineEdit(contents, parent) + { + setReadOnly(true); + setFrame(false); + setAlignment(Qt::AlignLeft); + setCursorPosition(0); + connect(this, SIGNAL(editingFinished()), SLOT(contentHasChanged())); + } + +//--------------------------------------------------------- +// contentHasChanged +//--------------------------------------------------------- + +void TLLineEdit::contentHasChanged() + { + setReadOnly(true); + setFrame(false); + if (isModified()) + emit contentChanged(text()); + setModified(false); + } + +//--------------------------------------------------------- +// mouseDoubleClickEvent +//--------------------------------------------------------- + +void TLLineEdit::mouseDoubleClickEvent(QMouseEvent*) + { + setReadOnly(false); + setFocus(); + setFrame(true); + } + +//--------------------------------------------------------- +// mousePressEvent +//--------------------------------------------------------- + +void TLLineEdit::mousePressEvent(QMouseEvent* ev) + { + QLineEdit::mousePressEvent(ev); + emit mousePress(); + } + diff --git a/muse/muse/tllineedit.h b/muse/muse/tllineedit.h new file mode 100644 index 00000000..56bfdd55 --- /dev/null +++ b/muse/muse/tllineedit.h @@ -0,0 +1,48 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __TLLINEEDIT_H__ +#define __TLLINEEDIT_H__ + +//--------------------------------------------------------- +// TLLineEdit +//--------------------------------------------------------- + +class TLLineEdit : public QLineEdit { + Q_OBJECT + + virtual void mouseDoubleClickEvent(QMouseEvent*); + virtual void mousePressEvent(QMouseEvent*); + + private slots: + void contentHasChanged(); + + signals: + void contentChanged(QString s); + void mousePress(); + + public: + TLLineEdit(const QString& contents, QWidget* parent = 0); + }; + +#endif + + + diff --git a/muse/muse/tlswidget.cpp b/muse/muse/tlswidget.cpp new file mode 100644 index 00000000..23b7fbc1 --- /dev/null +++ b/muse/muse/tlswidget.cpp @@ -0,0 +1,355 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "song.h" +#include "track.h" +#include "tlswidget.h" +#include "tlwlayout.h" +#include "icons.h" +#include "arranger.h" +#include "widgets/simplebutton.h" +#include "muse.h" +#include "ctrl/configmidictrl.h" +#include "ctrl/ctrldialog.h" +#include "midictrl.h" +#include "widgets/utils.h" + +//--------------------------------------------------------- +// TLSLayout +//--------------------------------------------------------- + +class TLSLayout : public QLayout { + QList itemList; + + public: + TLSLayout() {} + ~TLSLayout(); + + void addItem(QLayoutItem* item); + void insertWidget(int index, QWidget* item); + Qt::Orientations expandingDirections() const { return 0; } + bool hasHeightForWidth() const { return false; } + int count() const { return itemList.size(); } + void setGeometry(const QRect &rect); + QSize sizeHint() const { return ((QWidget*)parent())->size(); } + QLayoutItem *itemAt(int index) const { return itemList.value(index); } + QLayoutItem *takeAt(int idx) { + return idx >= 0 && idx < itemList.size() ? itemList.takeAt(idx) : 0; + } + }; + +//--------------------------------------------------------- +// TLSLayout +//--------------------------------------------------------- + +TLSLayout::~TLSLayout() + { + QLayoutItem* child; + while ((child = takeAt(0)) != 0) + delete child; + } + +//--------------------------------------------------------- +// insertWidget +//--------------------------------------------------------- + +void TLSLayout::insertWidget(int index, QWidget* item) + { + if (item->parent() == 0) + item->setParent((QWidget*)parent()); + itemList.insert(index, new QWidgetItem(item)); + update(); + } + +//--------------------------------------------------------- +// addItem +//--------------------------------------------------------- + +void TLSLayout::addItem(QLayoutItem* item) + { + itemList.append(item); + update(); + } + +//--------------------------------------------------------- +// setGeometry +//--------------------------------------------------------- + +void TLSLayout::setGeometry(const QRect& rect) + { + static const int labelWidth = 50; + int x1 = rect.x() + labelWidth; + int y = rect.y(); + int y2 = y + rect.height(); + + QLayoutItem *item = itemList.at(0); + QSize size(item->sizeHint()); + item->widget()->setGeometry(QRect(x1 - 18, y2 - 18-splitWidth, 18, 18)); + + item = itemList.at(1); + size = item->sizeHint(); + item->setGeometry(QRect(x1, rect.y(), + rect.width() - x1 - 2, trackRowHeight)); + } + +//--------------------------------------------------------- +// TLSWidget +//--------------------------------------------------------- + +TLSWidget::TLSWidget(Track* t, ArrangerTrack* atrack, TimeCanvas* timeC) + { + setAttribute(Qt::WA_NoBackground); + setAttribute(Qt::WA_StaticContents); + setAutoFillBackground(true); + + setMouseTracking(true); + _tc = timeC; + state = S_NORMAL; + + at = atrack; + _track = t; + _ctrlTrack = t; + + TLSLayout* l = new TLSLayout; + setLayout(l); + // + // track type + // + SimpleButton* minus = newMinusButton(); + minus->setToolTip(tr("Remove Subtrack")); + l->addWidget(minus); + + ctrlList = new QToolButton; + ctrlList->setText(tr("Ctrl")); + + connect(ctrlList, SIGNAL(clicked()), SLOT(showControllerList())); + + l->addWidget(ctrlList); + ctrlList->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + + connect(_track, SIGNAL(selectionChanged(bool)), SLOT(selectionChanged())); + connect(_track, SIGNAL(controllerChanged(int)), SLOT(controllerListChanged(int))); + connect(_track, SIGNAL(autoReadChanged(bool)), SLOT(autoReadChanged())); + connect(muse, SIGNAL(configChanged()), SLOT(configChanged())); + connect(minus, SIGNAL(clicked()), SLOT(labelMinusClicked())); + configChanged(); + } + +//--------------------------------------------------------- +// ctrl +//--------------------------------------------------------- + +Ctrl* TLSWidget::ctrl() const + { + return at->controller; + } + +//--------------------------------------------------------- +// height +//--------------------------------------------------------- + +int TLSWidget::cheight() const + { + return at->tw->height() - splitWidth; + } + +//--------------------------------------------------------- +// selectionChanged +//--------------------------------------------------------- + +void TLSWidget::selectionChanged() + { +// setFrameShadow(_track->selected() ? QFrame::Sunken : QFrame::Raised); + } + +//--------------------------------------------------------- +// configChanged +//--------------------------------------------------------- + +void TLSWidget::configChanged() + { + QColor c(_track->ccolor()); + QPalette p(palette()); + p.setColor(QPalette::Background, c.light(100)); + setPalette(p); + } + +//--------------------------------------------------------- +// showControllerList +//--------------------------------------------------------- + +bool TLSWidget::showControllerList() + { + Ctrl* c = ctrl(); + int id; + if (c) + id = c->id(); + else + id = CTRL_NO_CTRL; + for (;;) { + CtrlDialog cd(_ctrlTrack, id); + int rv = cd.exec(); + if (rv != 1) + return false; + id = cd.curId(); + if (id == CTRL_NO_CTRL) + return false; + if (id != CTRL_OTHER) + break; + ConfigMidiCtrl* mce = new ConfigMidiCtrl((MidiTrack*)_track); + mce->exec(); + delete mce; + } + setCtrl(id); + return true; + } + +//--------------------------------------------------------- +// setCtrl +//--------------------------------------------------------- + +bool TLSWidget::setCtrl(int ctrl) + { + if (ctrl == CTRL_NO_CTRL || ctrl == CTRL_OTHER) { + // this controller subtrack is new, ask user for + // controller: + return showControllerList(); + } + + if (_ctrlTrack && _ctrlTrack != _track) { + disconnect(_ctrlTrack, SIGNAL(controllerChanged(int)), this, SLOT(controllerListChanged(int))); + } + if (ctrl == CTRL_VELOCITY) { + at->controller = &veloList; + at->ctrl = CTRL_VELOCITY; + ctrlList->setText(tr("Velocity")); + _ctrlTrack = _track; + emit controllerChanged(at->ctrl); + } + else { + at->ctrl = ctrl; + at->controller = _track->getController(ctrl); + if (at->controller) { + _ctrlTrack = _track; + ctrlList->setText(at->controller->name()); + emit controllerChanged(ctrl); + } + } + return true; + } + +//--------------------------------------------------------- +// labelMinusClicked +//--------------------------------------------------------- + +void TLSWidget::labelMinusClicked() + { + emit minusClicked(this); + } + +//--------------------------------------------------------- +// mousePressEvent +//--------------------------------------------------------- + +void TLSWidget::mousePressEvent(QMouseEvent* ev) + { + if (ev->button() == Qt::RightButton) { + QMenu* menu = new QMenu(this); + QAction* a = menu->addAction(tr("Delete Controller")); + a->setData(0); + QAction* rv = menu->exec(ev->globalPos()); + if (rv == 0) + return; + emit minusClicked(this); + return; + } + song->selectTrack(_track); + + int y = ev->pos().y(); + int wh = height(); + starty = ev->globalPos().y(); + if (y > (wh - splitWidth)) { + state = S_DRAGBOTTOM; + emit startDrag(trackIdx); + } + } + +//--------------------------------------------------------- +// mouseReleaseEvent +//--------------------------------------------------------- + +void TLSWidget::mouseReleaseEvent(QMouseEvent*) + { + state = S_NORMAL; + } + +//--------------------------------------------------------- +// mouseMoveEvent +//--------------------------------------------------------- + +void TLSWidget::mouseMoveEvent(QMouseEvent* ev) + { + QPoint pos(ev->pos()); + + if (state == S_DRAGTOP) + emit drag(trackIdx-1, ev->globalPos().y() - starty); + else if (state == S_DRAGBOTTOM) + emit drag(trackIdx, ev->globalPos().y() - starty); + else { + int y = pos.y(); + int wh = height(); + if (y > (wh - splitWidth)) + setCursor(Qt::SizeVerCursor); + else + setCursor(Qt::ArrowCursor); + } + } + +//--------------------------------------------------------- +// controllerListChanged +// controller list for controller id changed +//--------------------------------------------------------- + +void TLSWidget::controllerListChanged(int id) + { + if (ctrl()->id() == id) + tc()->widget()->update(); + } + +//--------------------------------------------------------- +// autoReadChanged +//--------------------------------------------------------- + +void TLSWidget::autoReadChanged() + { + tc()->widget()->update(); + } + +//--------------------------------------------------------- +// paintEvent +//--------------------------------------------------------- + +void TLSWidget::paintEvent(QPaintEvent* ev) + { + QPainter p(this); + QRect r(ev->rect()); + p.fillRect(r, _track->ccolor()); + paintHLine(p, r.x(), r.x() + r.width(), height() - splitWidth); + } diff --git a/muse/muse/tlswidget.h b/muse/muse/tlswidget.h new file mode 100644 index 00000000..ccdfa3b8 --- /dev/null +++ b/muse/muse/tlswidget.h @@ -0,0 +1,83 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __TLSWIDGET_H__ +#define __TLSWIDGET_H__ + +class Track; +class ArrangerTrack; +class CtrlDialog; +class TimeCanvas; + +#include "ctrl/ctrleditor.h" + +//--------------------------------------------------------- +// TLSWidget +//--------------------------------------------------------- + +class TLSWidget : public QWidget, public CtrlEditor { + Q_OBJECT + + enum { S_NORMAL, S_DRAGTOP, S_DRAGBOTTOM, S_DRAG }; + int state; + + int trackIdx; + int starty; + Track* _track; // editor canvas is associated to this track + Track* _ctrlTrack; // track were ctrl belongs to + TimeCanvas* _tc; + QToolButton* ctrlList; + QLineEdit* nameEdit; + ArrangerTrack* at; + + TimeCanvas* tc() const { return _tc; } + Ctrl* ctrl() const; + int cheight() const; + + virtual void paintEvent(QPaintEvent*); + virtual void mousePressEvent(QMouseEvent*); + virtual void mouseReleaseEvent(QMouseEvent*); + virtual void mouseMoveEvent(QMouseEvent*); + + private slots: + void labelMinusClicked(); + bool showControllerList(); + void selectionChanged(); + void configChanged(); + void controllerListChanged(int); + void autoReadChanged(); + + signals: + void minusClicked(TLSWidget*); + void controllerChanged(int); + void startDrag(int idx); + void drag(int idx, int); + + public: + TLSWidget(Track*, ArrangerTrack*, TimeCanvas* tc); + Track* track() const { return _track; } + Track* ctrlTrack() const { return _ctrlTrack; } + bool setCtrl(int ctrl); + void setIdx(int n) { trackIdx = n; } + }; + +#endif + + diff --git a/muse/muse/tlwidget.cpp b/muse/muse/tlwidget.cpp new file mode 100644 index 00000000..fdf08d0b --- /dev/null +++ b/muse/muse/tlwidget.cpp @@ -0,0 +1,641 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "song.h" +#include "track.h" +#include "tlwidget.h" +#include "tlwlayout.h" +#include "tllineedit.h" +#include "icons.h" +#include "arranger.h" +#include "widgets/simplebutton.h" +#include "muse.h" +#include "trelement.h" +#include "gconfig.h" +#include "widgets/utils.h" +#include "trackdrag.h" +#include "synth.h" +#include "widgets/outportcombo.h" +#include "audio.h" +#include "midioutport.h" +#include "instruments/minstrument.h" + +//--------------------------------------------------------- +// TLWidget +//--------------------------------------------------------- + +TLWidget::TLWidget(Track* t, TrGroupList* tgl) + { + setAttribute(Qt::WA_OpaquePaintEvent); + setAutoFillBackground(true); + + setMouseTracking(true); + + state = S_NORMAL; + off = 0; + tel = tgl; + _track = t; + outPort = 0; + + bgColor = _track->ccolor(); + selectBgColor = bgColor.light(); + + QPalette p(palette()); + p.setColor(QPalette::Window, bgColor); + p.setColor(QPalette::Base, bgColor); + setPalette(p); + + l = new TLWidgetLayout(this); + configChanged(); + + connect(_track, SIGNAL(selectionChanged(bool)), SLOT(selectionChanged())); + setAcceptDrops(true); + connect(muse, SIGNAL(configChanged()), SLOT(configChanged())); + } + +//--------------------------------------------------------- +// selectionChanged +//--------------------------------------------------------- + +void TLWidget::selectionChanged() + { + update(); + } + +//--------------------------------------------------------- +// nameChanged +//--------------------------------------------------------- + +void TLWidget::nameChanged(QString s) + { + song->changeTrackName(_track, s); + nameEdit->setCursorPosition(0); + } + +//--------------------------------------------------------- +// selectTL +//--------------------------------------------------------- + +void TLWidget::select() + { + setFocus(); + song->selectTrack(_track); + } + +//--------------------------------------------------------- +// labelPlusClicked +//--------------------------------------------------------- + +void TLWidget::labelPlusClicked() + { + emit plusClicked(this); + } + +//--------------------------------------------------------- +// mousePressEvent +//--------------------------------------------------------- + +void TLWidget::mousePressEvent(QMouseEvent* ev) + { + enum { + CMD_REMOVE_TRACK, CMD_COPY_TRACK, CMD_SHOW_AUDIO_GUI, + CMD_SHOW_MIDI_GUI + }; + int button = ev->button(); + if (button == Qt::RightButton) { + QMenu* menu = new QMenu(this); + QAction* a = getAction("delete", this); + menu->addAction(a); + a->setData(CMD_REMOVE_TRACK); + if (_track->type() == Track::MIDI || _track->type() == Track::WAVE) { + a = menu->addAction(tr("Copy Track")); + a->setData(CMD_COPY_TRACK); + } + if (_track->type() == Track::AUDIO_SOFTSYNTH) { + SynthI* s = (SynthI*) _track; + if (s->hasGui()) { + menu->addSeparator(); + a = menu->addAction(tr("Show Gui")); + a->setData(CMD_SHOW_AUDIO_GUI); + a->setCheckable(true); + a->setChecked(s->guiVisible()); + } + } + else if (_track->type() == Track::MIDI_SYNTI) { + MidiSynti* s = (MidiSynti*) _track; + if (s->hasGui()) { + menu->addSeparator(); + a = menu->addAction(tr("Show Gui")); + a->setData(CMD_SHOW_MIDI_GUI); + a->setCheckable(true); + a->setChecked(s->guiVisible()); + } + } + + a = menu->exec(ev->globalPos()); + if (!a) + return; + int rv = a->data().toInt(); + switch (rv) { + default: + break; + case CMD_REMOVE_TRACK: + song->removeTrack(_track); + break; + case CMD_COPY_TRACK: + { + int idx = song->tracks()->indexOf(_track); + if (_track->type() == Track::MIDI) { + MidiTrack* t = new MidiTrack(); + t->clone((MidiTrack*)_track); + song->cmdInsertTrack(t, idx); + } + else { + WaveTrack* t = new WaveTrack(); + t->clone((WaveTrack*)_track); + song->cmdInsertTrack(t, idx); + } + } + break; + case CMD_SHOW_AUDIO_GUI: + { + SynthI* s = (SynthI*) _track; + s->showGui(!s->guiVisible()); + } + break; + case CMD_SHOW_MIDI_GUI: + { + MidiSynti* s = (MidiSynti*) _track; + s->showGui(!s->guiVisible()); + } + break; + } + return; + } + int y = ev->pos().y(); + int wh = height(); + starty = ev->globalPos().y(); + if (y > (wh - splitWidth)) { + state = S_DRAGBOTTOM; + emit startDrag(trackIdx); + } + else { + state = S_DRAG; + startDragPos = ev->pos(); + startDragTime = QTime::currentTime(); + select(); + } + } + +//--------------------------------------------------------- +// mouseReleaseEvent +//--------------------------------------------------------- + +void TLWidget::mouseReleaseEvent(QMouseEvent*) + { + state = S_NORMAL; + } + +//--------------------------------------------------------- +// mouseMoveEvent +//--------------------------------------------------------- + +void TLWidget::mouseMoveEvent(QMouseEvent* ev) + { + QPoint pos(ev->pos()); + + if (state == S_DRAGBOTTOM) + emit drag(trackIdx, ev->globalPos().y() - starty); + else if (state == S_DRAG) { + int t = startDragTime.msecsTo(QTime::currentTime()); + bool dragActive = (startDragPos - pos).manhattanLength() > + QApplication::startDragDistance() + || t > QApplication::startDragTime(); + if (dragActive) { + QDrag* d = new TrackDrag(_track, this); + d->start(Qt::MoveAction); + state = S_NORMAL; + } + } + else { + int y = pos.y(); + int wh = height(); + if (y > (wh - splitWidth)) + setCursor(Qt::SizeVerCursor); + else + setCursor(Qt::ArrowCursor); + } + } + +//--------------------------------------------------------- +// configChanged +//--------------------------------------------------------- + +void TLWidget::configChanged() + { + l->clear(); + wlist.clear(); + nameEdit = 0; + record = 0; + off = 0; + outChannel = 0; + outPort = 0; + + label = new QLabel; + label->setObjectName("trackLabel"); + l->addWidget(label); + label->setIndent(3); + + label->setText(_track->cname()); + label->setFixedHeight(11); + + plus = newPlusButton(); + l->addWidget(plus); + plus->setToolTip(tr("Add Subtrack")); + connect(plus, SIGNAL(clicked()), SLOT(labelPlusClicked())); + + for (iTrGroup i = tel->begin(); i != tel->end(); ++i) { + TrElementList& el = *i; + iTrElement k; + for (k = el.begin(); k != el.end(); ++k) { + int id = (*k)->id; + switch(id) { + case TR_NAME: + nameEdit = new TLLineEdit(_track->name(), this); + nameEdit->setFixedHeight(trackRowHeight); + connect(nameEdit, SIGNAL(contentChanged(QString)), SLOT(nameChanged(QString))); + connect(nameEdit, SIGNAL(mousePress()), SLOT(select())); + connect(_track, SIGNAL(nameChanged(const QString&)), nameEdit, SLOT(setText(const QString&))); + nameEdit->setToolTip(_track->clname() + " Name"); + l->addWidget(nameEdit); + wlist.push_back(nameEdit); + break; + + case TR_INSTRUMENT: + { + instrument = new QComboBox(this); + instrument->setFixedHeight(trackRowHeight); + MidiOutPort* op = (MidiOutPort*)_track; + MidiInstrument* mi = op->instrument(); + int idx = 0; + int curIdx = 0; + for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) { + instrument->addItem((*i)->iname()); + if ((*i)->iname() == mi->iname()) + curIdx = idx; + } + instrument->setCurrentIndex(curIdx); + connect(instrument, SIGNAL(activated(int)), SLOT(instrumentSelected(int))); + connect(op, SIGNAL(instrumentChanged()), SLOT(instrumentChanged())); + l->addWidget(instrument); + wlist.push_back(instrument); + } + break; + + case TR_PATCH: + { + // Ctrl* ctrl = _track->getController(CTRL_PROGRAM); + } + break; + + case TR_OFF: + { + off = newOffButton(); + off->setFixedSize(trackRowHeight, trackRowHeight); + off->setChecked(_track->off()); + connect(off, SIGNAL(clicked(bool)), SLOT(offToggled(bool))); + connect(_track, SIGNAL(offChanged(bool)), this, SLOT(updateOffState())); + l->addWidget(off); + wlist.push_back(off); + } + break; + + case TR_DRUMMAP: + { + SimpleButton* dm = newDrumMapButton(); + dm->setFixedSize(trackRowHeight, trackRowHeight); + dm->setChecked(((MidiTrack*)_track)->useDrumMap()); + connect(dm, SIGNAL(clicked(bool)), SLOT(drumMapToggled(bool))); + connect(_track, SIGNAL(useDrumMapChanged(bool)), dm, SLOT(setChecked(bool))); + l->addWidget(dm); + wlist.push_back(dm); + } + break; + + case TR_MUTE: + { + SimpleButton* mute = newMuteButton(); + mute->setFixedSize(trackRowHeight, trackRowHeight); + mute->setChecked(_track->isMute()); + connect(mute, SIGNAL(clicked(bool)), SLOT(muteToggled(bool))); + connect(_track, SIGNAL(muteChanged(bool)), mute, SLOT(setChecked(bool))); + l->addWidget(mute); + wlist.push_back(mute); + } + break; + + case TR_SOLO: + { + SimpleButton* solo = newSoloButton(); + solo->setFixedSize(trackRowHeight, trackRowHeight); + solo->setChecked(_track->solo()); + connect(solo, SIGNAL(clicked(bool)), SLOT(soloToggled(bool))); + connect(_track, SIGNAL(soloChanged(bool)), solo, SLOT(setChecked(bool))); + l->addWidget(solo); + wlist.push_back(solo); + } + break; + + case TR_MONITOR: + { + SimpleButton* monitor = newMonitorButton(); + monitor->setFixedSize(trackRowHeight+4, trackRowHeight); + monitor->setChecked(_track->monitor()); + connect(monitor, SIGNAL(clicked(bool)), SLOT(monitorToggled(bool))); + connect(_track, SIGNAL(monitorChanged(bool)), monitor, SLOT(setChecked(bool))); + l->addWidget(monitor); + wlist.push_back(monitor); + } + break; + + case TR_RECORD: + { + record = newRecordButton(); + record->setFixedSize(trackRowHeight, trackRowHeight); + record->setChecked(_track->recordFlag()); + connect(record, SIGNAL(clicked(bool)), SLOT(recordToggled(bool))); + connect(_track, SIGNAL(recordChanged(bool)), record, SLOT(setChecked(bool))); + l->addWidget(record); + wlist.push_back(record); + } + break; + + case TR_AREAD: + { + SimpleButton* b = newAutoReadButton(); + b->setFixedSize(trackRowHeight, trackRowHeight); + b->setChecked(_track->autoRead()); + connect(b, SIGNAL(clicked(bool)), SLOT(autoReadToggled(bool))); + connect(_track, SIGNAL(autoReadChanged(bool)), b, SLOT(setChecked(bool))); + l->addWidget(b); + wlist.push_back(b); + } + break; + + case TR_AWRITE: + { + SimpleButton* b = newAutoWriteButton(); + b->setFixedSize(trackRowHeight, trackRowHeight); + b->setChecked(_track->autoWrite()); + connect(b, SIGNAL(clicked(bool)), SLOT(autoWriteToggled(bool))); + connect(_track, SIGNAL(autoWriteChanged(bool)), b, SLOT(setChecked(bool))); + l->addWidget(b); + wlist.push_back(b); + } + break; + + case TR_OCHANNEL: + { + outChannel = new QSpinBox(this); + outChannel->setFixedSize(45, trackRowHeight); + outChannel->setRange(1, 16); + outChannel->setValue(((MidiTrack*)_track)->channelNo() + 1); + outChannel->setToolTip(tr("Midi Output Channel")); + l->addWidget(outChannel); + wlist.push_back(outChannel); + connect(outChannel, SIGNAL(valueChanged(int)), SLOT(setChannel(int))); + connect((MidiTrack*)_track, SIGNAL(channelChanged(int)), SLOT(channelChanged(int))); + } + break; + + default: + printf("TLWidget:: unknown element %d\n", id); + break; + } + } + } + updateOffState(); + selectionChanged(); // update selection state + l->update(); + } + +//--------------------------------------------------------- +// recordToggled +//--------------------------------------------------------- + +void TLWidget::recordToggled(bool val) + { + song->setRecordFlag(_track, !val); + } + +//--------------------------------------------------------- +// muteToggled +//--------------------------------------------------------- + +void TLWidget::muteToggled(bool val) + { + song->setMute(_track, val); + } + +//--------------------------------------------------------- +// monitorToggled +//--------------------------------------------------------- + +void TLWidget::monitorToggled(bool val) + { + _track->setMonitor(val); + } + +//--------------------------------------------------------- +// drumMapToggled +//--------------------------------------------------------- + +void TLWidget::drumMapToggled(bool val) + { + ((MidiTrack*)_track)->setUseDrumMap(val); + } + +//--------------------------------------------------------- +// offToggled +//--------------------------------------------------------- + +void TLWidget::offToggled(bool val) + { + song->setOff(_track, !val); + } + +//--------------------------------------------------------- +// soloToggled +//--------------------------------------------------------- + +void TLWidget::soloToggled(bool val) + { + song->setSolo(_track, val); + } + +//--------------------------------------------------------- +// autoReadToggled +//--------------------------------------------------------- + +void TLWidget::autoReadToggled(bool val) + { + song->setAutoRead(_track, val); + } + +//--------------------------------------------------------- +// autoWriteToggled +//--------------------------------------------------------- + +void TLWidget::autoWriteToggled(bool val) + { + song->setAutoWrite(_track, val); + } + +//--------------------------------------------------------- +// setOutPort +//--------------------------------------------------------- + +void TLWidget::setOutPort(int n) + { + outPort->setCurrentIndex(n); + } + +//--------------------------------------------------------- +// dragEnterEvent +//--------------------------------------------------------- + +void TLWidget::dragEnterEvent(QDragEnterEvent* event) + { + if (TrackDrag::canDecode(event)) + event->acceptProposedAction(); + } + +//--------------------------------------------------------- +// dropEvent +//--------------------------------------------------------- + +void TLWidget::dropEvent(QDropEvent* event) + { + Track* t; + TrackDrag::decode(event, t); + if (_track != t) + emit moveTrack(t, _track); + event->acceptProposedAction(); + } + +//--------------------------------------------------------- +// updateOffState +//--------------------------------------------------------- + +void TLWidget::updateOffState() + { + bool val = !_track->off(); + std::vector::iterator i = wlist.begin(); + for (; i != wlist.end(); ++i) { + if ((*i) != off) + (*i)->setEnabled(val); + } + if (off) + off->setChecked(!val); + } + +//--------------------------------------------------------- +// instrumentSelected +//--------------------------------------------------------- + +void TLWidget::instrumentSelected(int n) + { + MidiOutPort* op = (MidiOutPort*)_track; + int idx = 0; + for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) { + if (idx == n) { + op->setInstrument(*i); + break; + } + } + } + +//--------------------------------------------------------- +// instrumentChanged +//--------------------------------------------------------- + +void TLWidget::instrumentChanged() + { + MidiOutPort* op = (MidiOutPort*)_track; + MidiInstrument* mi = op->instrument(); + int idx = 0; + for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) { + if (*i == mi) { + instrument->setCurrentIndex(idx); + break; + } + } + } + +//--------------------------------------------------------- +// paintEvent +//--------------------------------------------------------- + +void TLWidget::paintEvent(QPaintEvent* ev) + { + QPainter p(this); + QRect r(ev->rect()); + QColor color(_track->selected() ? selectBgColor : bgColor); + p.fillRect(r, color); + + paintHLine(p, r.x(), r.x() + r.width(), height() - splitWidth); + QPalette pl = nameEdit->palette(); + pl.setColor(QPalette::Window, color); + pl.setColor(QPalette::Base, color); + nameEdit->setPalette(pl); + + // The selected track will get a 4 pixel red bar to the left + if ( _track->selected()) { + QColor color(200,10,10); + QRect qr(0, 0, 4, r.height()-splitWidth); + p.fillRect(qr, color); + } + } + +//--------------------------------------------------------- +// channelChanged +// SLOT: callend when channel routing of track has +// changed +// - channel starts counting at 0 +//--------------------------------------------------------- + +void TLWidget::channelChanged(int channel) + { + if (outChannel->value() == channel + 1) + return; + outChannel->setValue(channel + 1); + } + +//--------------------------------------------------------- +// setChannel +// - called when channel spinbox value changed +// - channel starts counting at 1 +//--------------------------------------------------------- + +void TLWidget::setChannel(int channel) + { + ((MidiTrack*)_track)->setChannel(channel - 1); + } + diff --git a/muse/muse/tlwidget.h b/muse/muse/tlwidget.h new file mode 100644 index 00000000..fbe428e2 --- /dev/null +++ b/muse/muse/tlwidget.h @@ -0,0 +1,105 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __TLWIDGET_H__ +#define __TLWIDGET_H__ + +class Track; +class TrGroupList; +class TLWidgetLayout; +class SimpleButton; + +//--------------------------------------------------------- +// TLWidget +//--------------------------------------------------------- + +class TLWidget : public QWidget { + Q_OBJECT + + enum { S_NORMAL, S_DRAGBOTTOM, S_DRAG }; + int state; + + int trackIdx; + int starty; + Track* _track; + QColor bgColor; + QColor selectBgColor; + + QLineEdit* nameEdit; + TLWidgetLayout* l; + TrGroupList* tel; + QSpinBox* outChannel; + QComboBox* outPort; + SimpleButton* off; + SimpleButton* plus; + SimpleButton* record; + std::vector wlist; + QComboBox* instrument; + QLabel* label; + + QTime startDragTime; + QPoint startDragPos; + + virtual void paintEvent(QPaintEvent*); + virtual void mousePressEvent(QMouseEvent*); + virtual void mouseReleaseEvent(QMouseEvent*); + virtual void mouseMoveEvent(QMouseEvent*); + virtual void dragEnterEvent(QDragEnterEvent*); + virtual void dropEvent(QDropEvent*); + + signals: + void startDrag(int idx); + void drag(int idx, int); + + private slots: + void nameChanged(QString); + void labelPlusClicked(); + void configChanged(); + void recordToggled(bool); + void muteToggled(bool); + void offToggled(bool); + void soloToggled(bool); + void monitorToggled(bool); + void drumMapToggled(bool); + void selectionChanged(); + void setOutPort(int); + void autoReadToggled(bool val); + void autoWriteToggled(bool val); + void instrumentSelected(int); + void instrumentChanged(); + void updateOffState(); + void channelChanged(int); + void setChannel(int); + + public slots: + void select(); + + signals: + void plusClicked(TLWidget*); + void moveTrack(Track* src, Track* dst); + + public: + TLWidget(Track* t, TrGroupList*); + Track* track() const { return _track; } + void setIdx(int n) { trackIdx = n; } + }; + +#endif + diff --git a/muse/muse/tlwlayout.cpp b/muse/muse/tlwlayout.cpp new file mode 100644 index 00000000..076f07cf --- /dev/null +++ b/muse/muse/tlwlayout.cpp @@ -0,0 +1,144 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "tlwlayout.h" +#include "arranger.h" +#include "gui.h" + +//--------------------------------------------------------- +// TLWidgetLayout +//--------------------------------------------------------- + +TLWidgetLayout::TLWidgetLayout(QWidget *parent) + : QLayout(parent) + { + setMargin(0); + setSpacing(0); + } + +TLWidgetLayout::TLWidgetLayout() + { + setMargin(0); + setSpacing(0); + } + +//--------------------------------------------------------- +// takeAt +//--------------------------------------------------------- + +QLayoutItem *TLWidgetLayout::takeAt(int index) + { + if (index >= 0 && index < itemList.size()) + return itemList.takeAt(index); + else + return 0; + } + +//--------------------------------------------------------- +// setGeometry +//--------------------------------------------------------- + +void TLWidgetLayout::setGeometry(const QRect &rect) + { + int n = itemList.size(); + if (n < 2) + return; + + static const int labelWidth = 50; + int x1 = rect.x() + labelWidth; + int x2 = rect.x() + rect.width(); + int y = rect.y() + 1; + int y2 = y + rect.height() - splitWidth; + int dh = trackRowHeight; + + QLayoutItem* item = itemList.at(0); + QSize size(item->sizeHint()); + item->setGeometry(QRect(rect.x(), rect.y(), size.width(), size.height())); + + item = itemList.at(1); + item->setGeometry(QRect(x1 - 18, y2 - 19, 18, 18)); + + itemList.at(2)->setGeometry(QRect(x1, y, x2-x1, dh)); + if (n <= 3) + return; + + y += dh; + if ((y + itemList.at(3)->sizeHint().height()) > y2) { + for (int i = 3; i < n; ++i) + itemList.at(i)->setGeometry(QRect(-1000, -1000, 0, 0)); + return; + } + int x = x1; + + for (int i = 3; i < n; ++i) { + QLayoutItem *item = itemList.at(i); + QSize size(item->sizeHint()); + + if ((x > x1) && ((x + size.width()) > x2)) { + x = x1; + y += dh; + if ((y + size.height()) > y2) { + for (; i < n; ++i) + itemList.at(i)->setGeometry(QRect(-1000, -1000, 0, 0)); + return; + } + } + item->setGeometry(QRect(x, y, size.width(), dh)); + x += size.width(); + } + } + +//--------------------------------------------------------- +// sizeHint +//--------------------------------------------------------- + +QSize TLWidgetLayout::sizeHint() const + { + return minimumSize(); + } + +//--------------------------------------------------------- +// minimumSize +//--------------------------------------------------------- + +QSize TLWidgetLayout::minimumSize() const + { + QSize size; + QLayoutItem *item; + foreach (item, itemList) + size = size.expandedTo(item->minimumSize()); + + size += QSize(2*margin(), 2*margin()); + return size; + } + +//--------------------------------------------------------- +// clear +//--------------------------------------------------------- + +void TLWidgetLayout::clear() + { + QLayoutItem* child; + while ((child = takeAt(0)) != 0) { + delete child->widget(); + delete child; + } + } + diff --git a/muse/muse/tlwlayout.h b/muse/muse/tlwlayout.h new file mode 100644 index 00000000..1a9cc914 --- /dev/null +++ b/muse/muse/tlwlayout.h @@ -0,0 +1,51 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __TLWLAYOUT_H__ +#define __TLWLAYOUT_H__ + +//--------------------------------------------------------- +// TLWidgetLayout +//--------------------------------------------------------- + +class TLWidgetLayout : public QLayout { + QList itemList; + + int doLayout(const QRect& rect, bool testOnly) const; + + public: + TLWidgetLayout(QWidget* parent); + TLWidgetLayout(); + ~TLWidgetLayout() { clear(); } + + void addItem(QLayoutItem* item) { itemList.append(item); } + Qt::Orientations expandingDirections() const { return 0; } + bool hasHeightForWidth() const { return false; } + int count() const { return itemList.size(); } + QSize minimumSize() const; + void setGeometry(const QRect &rect); + QSize sizeHint() const; + QLayoutItem *itemAt(int index) const { return itemList.value(index); } + QLayoutItem *takeAt(int index); + void clear(); + }; + +#endif + diff --git a/muse/muse/trackdrag.cpp b/muse/muse/trackdrag.cpp new file mode 100644 index 00000000..beab87dd --- /dev/null +++ b/muse/muse/trackdrag.cpp @@ -0,0 +1,61 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "trackdrag.h" + +class Track; +const char TrackDrag::type[] = "application/muse/track"; + +//--------------------------------------------------------- +// TrackDrag +//--------------------------------------------------------- + +TrackDrag::TrackDrag(Track* track, QWidget* src) + : QDrag(src) + { + QByteArray a((char*)&track, sizeof(track)); + QMimeData* mimeData = new QMimeData; + mimeData->setData(type, a); + setMimeData(mimeData); + } + +//--------------------------------------------------------- +// canDecode +//--------------------------------------------------------- + +bool TrackDrag::canDecode(const QMimeSource* s) + { + return !strcmp(s->format(0), type); + } + +//--------------------------------------------------------- +// decode +//--------------------------------------------------------- + +bool TrackDrag::decode(const QMimeSource* s, Track*& p) + { + QByteArray a = s->encodedData(type); + p = (Track*)((a[0] & 0xff) + | (a[1] & 0xff) << 8 + | (a[2] & 0xff) << 16 + | (a[3] & 0xff) << 24); + return true; + } + diff --git a/muse/muse/trackdrag.h b/muse/muse/trackdrag.h new file mode 100644 index 00000000..083a94b3 --- /dev/null +++ b/muse/muse/trackdrag.h @@ -0,0 +1,42 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __TRACKDRAG_H__ +#define __TRACKDRAG_H__ + +class Track; + +//--------------------------------------------------------- +// TrackDrag +//--------------------------------------------------------- + +class TrackDrag : public QDrag { + static const char type[]; + Q_OBJECT + + public: + TrackDrag(Track*, QWidget* src); + static bool canDecode(const QMimeSource*); + static bool decode(const QMimeSource* s, Track*& p); + }; + + +#endif + diff --git a/muse/muse/trackinfo.cpp b/muse/muse/trackinfo.cpp new file mode 100644 index 00000000..1a62b1c0 --- /dev/null +++ b/muse/muse/trackinfo.cpp @@ -0,0 +1,553 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "arranger.h" +#include "widgets/outportcombo.h" +#include "instruments/minstrument.h" +#include "midiedit/drummap.h" +#include "midictrl.h" +#include "song.h" +#include "trackinfo.h" +#include "synth.h" +#include "tllineedit.h" +#include "audio.h" +#include "gui.h" +#include "midioutport.h" +#include "midiinport.h" + +static QColor labelColor(140, 140, 255); + +//--------------------------------------------------------- +// createTrackInfo +//--------------------------------------------------------- + +TrackInfo* Arranger::createTrackInfo() + { + Track::TrackType t = _curTrack->type(); + switch (t) { + case Track::MIDI: return new MidiTrackInfo(); + case Track::AUDIO_OUTPUT: return new AudioOutputInfo(); + case Track::AUDIO_GROUP: return new AudioGroupInfo(); + case Track::WAVE: return new WaveTrackInfo(); + case Track::AUDIO_INPUT: return new AudioInputInfo(); + case Track::AUDIO_SOFTSYNTH: return new SynthIInfo(); + case Track::MIDI_OUT: return new MidiOutPortInfo(); + case Track::MIDI_IN: return new MidiInPortInfo(); + case Track::MIDI_SYNTI: return new MidiSynthIInfo(); + default: + printf("Arranger::createTrackInfo: type %d\n", t); + abort(); + } + } + +//--------------------------------------------------------- +// TrackInfo +//--------------------------------------------------------- + +TrackInfo::TrackInfo() + : QWidget() + { + track = 0; + label = new QLabel; + label->setToolTip(tr("Track Type")); + label->setLineWidth(2); + label->setFrameStyle(QFrame::Panel | QFrame::Raised); + label->setAutoFillBackground(true); + QPalette p = label->palette(); + p.setColor(QPalette::Background, labelColor); + label->setPalette(p); + + name = new TLLineEdit(""); + name->setToolTip(tr("Track Name")); + name->setMaximumHeight(24); + + grid = new QGridLayout; + grid->setMargin(0); + grid->setSpacing(0); + setLayout(grid); + + grid->addWidget(label, 0, 0, 1, 2); + grid->addWidget(name, 1, 0, 1, 2); + connect(name, SIGNAL(contentChanged(QString)), SLOT(nameChanged(QString))); + connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int))); +// resize(QSize(infoWidth, height())); + } + +//--------------------------------------------------------- +// nameChanged +//--------------------------------------------------------- + +void TrackInfo::nameChanged(QString s) + { + song->changeTrackName(track, s); + name->setCursorPosition(0); + } + +//--------------------------------------------------------- +// init +//--------------------------------------------------------- + +void TrackInfo::init(Track* t) + { + track = t; + if (t == 0) + return; + label->setText(track->clname()); + name->setText(track->name()); + connect(track, SIGNAL(nameChanged(const QString&)), name, SLOT(setText(const QString&))); + } + +//--------------------------------------------------------- +// songChanged +//--------------------------------------------------------- + +void TrackInfo::songChanged(int val) + { + if ((val & SC_ROUTE) && track) + init(track); + } + +//--------------------------------------------------------- +// MidiTrackInfo +//--------------------------------------------------------- + +MidiTrackInfo::MidiTrackInfo() + : TrackInfo() + { + QWidget* midiTrackInfo = new QWidget; + mt.setupUi(midiTrackInfo); + + QWidget* midiPortInfo = new QWidget; + mp.setupUi(midiPortInfo); + + grid->addWidget(midiTrackInfo, 2, 0, 1, 2); + + channel = new QComboBox; + channel->setMaximumHeight(24); + for (int ch = 0; ch < MIDI_CHANNELS; ++ch) + channel->addItem(tr("Channel %1").arg(ch+1), ch); + grid->addWidget(channel, 3, 0, 1, 2); + + QLabel* label = new QLabel; + label->setText(tr("Midi Port")); + label->setLineWidth(2); + label->setFrameStyle(QFrame::Panel | QFrame::Raised); + label->setAutoFillBackground(true); + QPalette p = label->palette(); + p.setColor(QPalette::Background, labelColor); + label->setPalette(p); + grid->addWidget(label, 4, 0, 1, 2); + + port = new QComboBox; + port->setMaximumHeight(24); + grid->addWidget(port, 5, 0, 1, 2); + grid->addWidget(midiPortInfo, 6, 0, 1, 2); + grid->setRowStretch(grid->rowCount(), 100); + + pop = new QMenu(mt.patch); + + connect(mt.transposition, SIGNAL(valueChanged(int)), SLOT(transpositionChanged(int))); + connect(mt.velocity, SIGNAL(valueChanged(int)), SLOT(velocityChanged(int))); + connect(mt.delay, SIGNAL(valueChanged(int)), SLOT(delayChanged(int))); + connect(mt.length, SIGNAL(valueChanged(int)), SLOT(lenChanged(int))); + connect(mt.compression, SIGNAL(valueChanged(int)), SLOT(iKomprChanged(int))); + connect(mt.patch, SIGNAL(clicked()), SLOT(patchClicked())); + connect(port, SIGNAL(activated(int)), SLOT(portSelected(int))); + connect(mp.instrument, SIGNAL(activated(int)), SLOT(instrumentSelected(int))); + connect(mp.deviceId, SIGNAL(valueChanged(int)), SLOT(deviceIdChanged(int))); + connect(song, SIGNAL(autoReadChanged(Track*,bool)), SLOT(autoChanged(Track*,bool))); + connect(song, SIGNAL(autoWriteChanged(Track*,bool)), SLOT(autoChanged(Track*,bool))); + } + +//--------------------------------------------------------- +// init +//--------------------------------------------------------- + +void MidiTrackInfo::init(Track* t) + { + MidiTrack* midiTrack = (MidiTrack*)&*t; + if (t != track) { + if (track) { + disconnect(channel, 0, track, 0); + disconnect(track, 0, channel, 0); + } + connect(channel, SIGNAL(activated(int)), midiTrack, SLOT(setChannel(int))); + connect(midiTrack,SIGNAL(channelChanged(int)), channel, SLOT(setCurrentIndex(int))); + } + + TrackInfo::init(t); + mt.transposition->setValue(midiTrack->transposition()); + mt.delay->setValue(midiTrack->delay()); + mt.length->setValue(midiTrack->len()); + mt.velocity->setValue(midiTrack->velocity()); + mt.compression->setValue(midiTrack->compression()); + + mp.instrument->clear(); + foreach(MidiInstrument* mi, midiInstruments) + mp.instrument->addItem(mi->iname()); + + RouteList* rl = track->outRoutes(); + Track* outputTrack = 0; + if (!rl->isEmpty()) + outputTrack = (*rl)[0].dst.track; + + port->clear(); + port->addItem("---", QVariant::fromValue(0)); + foreach(MidiOutPort* mp, *(song->midiOutPorts())) + port->addItem(mp->name(), QVariant::fromValue(mp)); + foreach(SynthI* s, *(song->syntis())) + port->addItem(s->name(), QVariant::fromValue(s)); + if (outputTrack) { + int idx = port->findText(outputTrack->name()); + port->setCurrentIndex(idx == -1 ? 0 : idx); + } + + channel->setCurrentIndex(midiTrack->channelNo()); + + connect(track, SIGNAL(controllerChanged(int)), SLOT(controllerChanged(int))); + if (outputTrack && outputTrack->type() == Track::MIDI_OUT) + connect(outputTrack, SIGNAL(instrumentChanged()), SLOT(instrumentChanged())); + + instrumentChanged(); // setup instrument + + // enable instrument selection only for tracks routed to a + // midi out port: + mp.instrument->setEnabled(outputTrack && (outputTrack->type() == Track::MIDI_OUT)); + + if (!rl->isEmpty()) { + mp.deviceId->setValue(midiTrack->deviceId()); + autoChanged(track, false); // update enable + int val = midiTrack->ctrlVal(CTRL_PROGRAM).i; + int channelno = midiTrack->channelNo(); + mt.patch->setText(midiTrack->instrument()->getPatchName(channelno, val)); + } + else { + channel->setCurrentIndex(0); + port->setCurrentIndex(0); + mp.instrument->addItem("--"); + mp.instrument->setCurrentIndex(0); + mt.patch->setText("--"); + } + } + +//--------------------------------------------------------- +// portSelected +//--------------------------------------------------------- + +void MidiTrackInfo::portSelected(int idx) + { + QVariant v(port->itemData(idx)); + Track* outputTrack = (Track*)v.value(); + if (outputTrack == 0) + return; + RouteList* rl = track->outRoutes(); + if (rl->isEmpty()) + return; + Route r = (*rl)[0]; + audio->msgRemoveRoute(r); + r.dst.track = outputTrack; + audio->msgAddRoute(r); + song->update(SC_ROUTE); + } + +//--------------------------------------------------------- +// controllerChanged +//--------------------------------------------------------- + +void MidiTrackInfo::controllerChanged(int id) + { + if (id == CTRL_PROGRAM) { + MidiInstrument* mi = track->instrument(); + int val = track->ctrlVal(id).i; + mt.patch->setText(mi->getPatchName(((MidiTrack*)&*track)->channelNo(), val)); + } + } + +//--------------------------------------------------------- +// instrumentChanged +//--------------------------------------------------------- + +void MidiTrackInfo::instrumentChanged() + { + MidiInstrument* mi = track->instrument(); + mp.instrument->setCurrentIndex(midiInstruments.indexOf(mi)); + } + +//--------------------------------------------------------- +// autoChanged +//--------------------------------------------------------- + +void MidiTrackInfo::autoChanged(Track* t, bool) + { + if (t != track) + return; + bool ar = t->autoRead(); + bool aw = t->autoWrite(); + bool en = !ar || (ar && aw); + mt.patch->setEnabled(en); + } + +//--------------------------------------------------------- +// transpositionChanged +//--------------------------------------------------------- + +void MidiTrackInfo::transpositionChanged(int val) + { + ((MidiTrack*)&*track)->setTransposition(val); + } + +//--------------------------------------------------------- +// patchClicked +//--------------------------------------------------------- + +void MidiTrackInfo::patchClicked() + { + MidiInstrument* mi = track->instrument(); + mi->populatePatchPopup(pop, 0); + + QAction* rv = pop->exec(mt.patch->mapToGlobal(QPoint(10,5))); + if (rv != 0) { + CVal cval; + cval.i = rv->data().toInt(); + song->setControllerVal(track, CTRL_PROGRAM, cval); + } + } + +//--------------------------------------------------------- +// instrumentSelected +//--------------------------------------------------------- + +void MidiTrackInfo::instrumentSelected(int n) + { + RouteList* rl = track->outRoutes(); + if (rl->isEmpty()) + return; + Track* outTrack = (*rl)[0].dst.track; + if (outTrack->type() == Track::MIDI_OUT) + ((MidiOutPort*)outTrack)->setInstrument(midiInstruments[n]); + } + +//--------------------------------------------------------- +// velocityChanged +//--------------------------------------------------------- + +void MidiTrackInfo::velocityChanged(int val) + { + ((MidiTrack*)&*track)->setVelocity(val); + } + +//--------------------------------------------------------- +// delayChanged +//--------------------------------------------------------- + +void MidiTrackInfo::delayChanged(int val) + { + ((MidiTrack*)&*track)->setDelay(val); + } + +//--------------------------------------------------------- +// lenChanged +//--------------------------------------------------------- + +void MidiTrackInfo::lenChanged(int val) + { + ((MidiTrack*)&*track)->setLen(val); + } + +//--------------------------------------------------------- +// iKomprChanged +//--------------------------------------------------------- + +void MidiTrackInfo::iKomprChanged(int val) + { + ((MidiTrack*)&*track)->setCompression(val); + } + +//--------------------------------------------------------- +// deviceIdChanged +//--------------------------------------------------------- + +void MidiTrackInfo::deviceIdChanged(int val) + { + ((MidiTrack*)&*track)->setDeviceId(val); + } + +//--------------------------------------------------------- +// AudioOutputInfo +//--------------------------------------------------------- + +AudioOutputInfo::AudioOutputInfo() + : TrackInfo() + { + grid->setRowStretch(grid->rowCount(), 100); + } + +//--------------------------------------------------------- +// AudioInputInfo +//--------------------------------------------------------- + +AudioInputInfo::AudioInputInfo() + : TrackInfo() + { + grid->setRowStretch(grid->rowCount(), 100); + } + +//--------------------------------------------------------- +// AudioGroupInfo +//--------------------------------------------------------- + +AudioGroupInfo::AudioGroupInfo() + : TrackInfo() + { + grid->setRowStretch(grid->rowCount(), 100); + } + +//--------------------------------------------------------- +// AudioAuxInfo +//--------------------------------------------------------- + +AudioAuxInfo::AudioAuxInfo() + : TrackInfo() + { + grid->setRowStretch(grid->rowCount(), 100); + } + +//--------------------------------------------------------- +// WaveTrackInfo +//--------------------------------------------------------- + +WaveTrackInfo::WaveTrackInfo() + : TrackInfo() + { + grid->setRowStretch(grid->rowCount(), 100); + } + +//--------------------------------------------------------- +// SynthIInfo +//--------------------------------------------------------- + +SynthIInfo::SynthIInfo() + : TrackInfo() + { + grid->setRowStretch(grid->rowCount(), 100); + } + +//--------------------------------------------------------- +// MidiSynthIInfo +//--------------------------------------------------------- + +MidiSynthIInfo::MidiSynthIInfo() + : TrackInfo() + { + grid->setRowStretch(grid->rowCount(), 100); + } + +//--------------------------------------------------------- +// MidiOutPortInfo +//--------------------------------------------------------- + +MidiOutPortInfo::MidiOutPortInfo() + : TrackInfo() + { + QWidget* midiPortInfo = new QWidget; + mp.setupUi(midiPortInfo); + grid->addWidget(midiPortInfo, 2, 0, 1, 2); + + grid->setRowStretch(grid->rowCount(), 100); + + connect(mp.instrument, SIGNAL(activated(int)), SLOT(instrumentSelected(int))); + connect(mp.deviceId, SIGNAL(valueChanged(int)), SLOT(deviceIdChanged(int))); + } + +//--------------------------------------------------------- +// init +//--------------------------------------------------------- + +void MidiOutPortInfo::init(Track* t) + { + TrackInfo::init(t); + + MidiOutPort* op = (MidiOutPort*)&*track; + MidiInstrument* mi = op->instrument(); + int idx = 0; + int curIdx = 0; + mp.instrument->clear(); + for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) { + mp.instrument->addItem((*i)->iname()); + if ((*i)->iname() == mi->iname()) + curIdx = idx; + } + mp.instrument->setCurrentIndex(curIdx); + mp.deviceId->setValue(op->deviceId()); + connect(t, SIGNAL(instrumentChanged()), SLOT(instrumentChanged())); + } + +//--------------------------------------------------------- +// deviceIdChanged +//--------------------------------------------------------- + +void MidiOutPortInfo::deviceIdChanged(int val) + { + ((MidiOutPort*)&*track)->setDeviceId(val); + } + +//--------------------------------------------------------- +// instrumentChanged +//--------------------------------------------------------- + +void MidiOutPortInfo::instrumentChanged() + { + MidiOutPort* op = (MidiOutPort*)&*track; + MidiInstrument* mi = op->instrument(); + int idx = 0; + for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) { + if (*i == mi) { + mp.instrument->setCurrentIndex(idx); + break; + } + } + } + +//--------------------------------------------------------- +// instrumentSelected +//--------------------------------------------------------- + +void MidiOutPortInfo::instrumentSelected(int n) + { + MidiOutPort* op = (MidiOutPort*)&*track; + int idx = 0; + for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) { + if (idx == n) { + op->setInstrument(*i); + break; + } + } + } + +//--------------------------------------------------------- +// MidiInPortInfo +//--------------------------------------------------------- + +MidiInPortInfo::MidiInPortInfo() + : TrackInfo() + { + grid->setRowStretch(grid->rowCount(), 100); + } + diff --git a/muse/muse/trackinfo.h b/muse/muse/trackinfo.h new file mode 100644 index 00000000..bea98d70 --- /dev/null +++ b/muse/muse/trackinfo.h @@ -0,0 +1,203 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __TRACKINFO_H__ +#define __TRACKINFO_H__ + +#include "ui_miditrackinfo.h" +#include "ui_midiportinfo.h" + +class Track; +class MidiTrack; +class AudioOutput; +class AudioInput; +class AudioGroup; +class AudioAux; +class SynthI; +class MidiInPort; +class MidiOutPort; +class MidiChannel; +class WaveTrack; +class TLLineEdit; + +//--------------------------------------------------------- +// TrackInfo +//--------------------------------------------------------- + +class TrackInfo : public QWidget { + Q_OBJECT + + QLabel* label; + TLLineEdit* name; + + protected: + QGridLayout* grid; + QPointer track; + + private slots: + void nameChanged(QString s); + void songChanged(int); + + public: + TrackInfo(); + virtual void init(Track*); + }; + +//--------------------------------------------------------- +// MidiTrackInfo +//--------------------------------------------------------- + +class MidiTrackInfo : public TrackInfo { + Q_OBJECT + + Ui::MidiTrackInfoBase mt; + Ui::MidiPortInfoBase mp; + QComboBox* port; + QComboBox* channel; + QMenu* pop; + + private slots: + void transpositionChanged(int val); + void velocityChanged(int val); + void delayChanged(int val); + void lenChanged(int val); + void iKomprChanged(int val); + void patchClicked(); + void instrumentSelected(int); + void instrumentChanged(); + void autoChanged(Track*,bool); + void controllerChanged(int); + void portSelected(int); + void deviceIdChanged(int); + + public: + MidiTrackInfo(); + virtual void init(Track*); + }; + +//--------------------------------------------------------- +// AudioOutputInfo +//--------------------------------------------------------- + +class AudioOutputInfo : public TrackInfo { + Q_OBJECT + + public: + AudioOutputInfo(); + }; + +//--------------------------------------------------------- +// AudioInputInfo +//--------------------------------------------------------- + +class AudioInputInfo : public TrackInfo { + Q_OBJECT + + public: + AudioInputInfo(); + }; + +//--------------------------------------------------------- +// AudioGroupInfo +//--------------------------------------------------------- + +class AudioGroupInfo : public TrackInfo { + Q_OBJECT + + public: + AudioGroupInfo(); + }; + +//--------------------------------------------------------- +// AudioAuxInfo +//--------------------------------------------------------- + +class AudioAuxInfo : public TrackInfo { + Q_OBJECT + + public: + AudioAuxInfo(); + }; + +//--------------------------------------------------------- +// WaveTrackInfo +//--------------------------------------------------------- + +class WaveTrackInfo : public TrackInfo { + Q_OBJECT + + public: + WaveTrackInfo(); + }; + +//--------------------------------------------------------- +// SynthIInfo +//--------------------------------------------------------- + +class SynthIInfo : public TrackInfo { + Q_OBJECT + + public: + SynthIInfo(); + }; + +//--------------------------------------------------------- +// MidiSynthIInfo +//--------------------------------------------------------- + +class MidiSynthIInfo : public TrackInfo { + Q_OBJECT + + public: + MidiSynthIInfo(); + }; + +//--------------------------------------------------------- +// MidiOutPortInfo +//--------------------------------------------------------- + +class MidiOutPortInfo : public TrackInfo { + Q_OBJECT + + Ui::MidiPortInfoBase mp; + + private slots: + void instrumentSelected(int); + void instrumentChanged(); + void deviceIdChanged(int); + + public: + MidiOutPortInfo(); + virtual void init(Track*); + }; + +//--------------------------------------------------------- +// MidiInPortInfo +//--------------------------------------------------------- + +class MidiInPortInfo : public TrackInfo { + Q_OBJECT + + public: + MidiInPortInfo(); + }; + +#endif + diff --git a/muse/muse/trelement.h b/muse/muse/trelement.h new file mode 100644 index 00000000..4c702ae2 --- /dev/null +++ b/muse/muse/trelement.h @@ -0,0 +1,63 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __TR_ELEMENT_H__ +#define __TR_ELEMENT_H__ + +#include "track.h" + +//--------------------------------------------------------- +// TrElement +// describes a configurable gui element of the +// track list +//--------------------------------------------------------- + +enum { + TR_NAME, TR_MUTE, TR_OFF, TR_SOLO, TR_RECORD, TR_AREAD, TR_AWRITE, + TR_OCHANNEL, TR_MONITOR, TR_DRUMMAP, TR_INSTRUMENT, TR_PATCH + }; + +struct TrElement { + int id; + int grp; // default group + const char* name; + int trackMask; + + TrElement(int i, int g, const char* s, int m) + : id(i), grp(g), name(s), trackMask(m) {} + }; + +//--------------------------------------------------------- +// TrGroup +// TrElements are grouped +//--------------------------------------------------------- + +typedef std::list TrElementList; +typedef TrElementList::iterator iTrElement; + +class TrGroupList : public std::list { + }; +typedef TrGroupList::iterator iTrGroup; + +extern const TrElement trElements[]; +extern const int nTrElements; +extern TrGroupList glist[Track::TRACK_TYPES]; + +#endif diff --git a/muse/muse/wave.cpp b/muse/muse/wave.cpp index 41682d88..dca9843b 100644 --- a/muse/muse/wave.cpp +++ b/muse/muse/wave.cpp @@ -26,7 +26,7 @@ #include "wave.h" #include "muse.h" #include "widgets/filedialog.h" -#include "arranger/arranger.h" +#include "arranger.h" #include "globals.h" #include "event.h" #include "audio.h" @@ -65,9 +65,9 @@ static bool copyWaveFileToProject(const QString& path) // we cannot easily check for identity if destination // file is sample rate converted // - // for now we assume that the file has already + // for now we assume that the file has already // be imported: - // + // printf("File already exists\n"); return true; } @@ -90,7 +90,7 @@ static bool copyWaveFileToProject(const QString& path) SNDFILE* sfDst = sf_open(dstFile.fileName().toLatin1().data(), SFM_WRITE, &sfinfoDst); if (sfDst == 0) { - printf("Cannot open destination file<%s>: %s\n", + printf("Cannot open destination file<%s>: %s\n", dstFile.fileName().toLatin1().data(), strerror(errno)); return false; } @@ -119,7 +119,7 @@ static bool copyWaveFileToProject(const QString& path) bool returnValue = true; if (sfinfoSrc.samplerate != AL::sampleRate) { // TODO: convertsample rate - printf("wave file has samplerate of %d, our project has %d\n", + printf("wave file has samplerate of %d, our project has %d\n", sfinfoSrc.samplerate,AL::sampleRate); int srcType = SRC_SINC_MEDIUM_QUALITY; @@ -161,7 +161,7 @@ static bool copyWaveFileToProject(const QString& path) int rv = src_process(src, &data); if (rv > 0) { - printf("error sampe rate conversion: %s\n", + printf("error sampe rate conversion: %s\n", src_strerror(rv)); src_delete(src); returnValue = false; @@ -171,7 +171,7 @@ static bool copyWaveFileToProject(const QString& path) // write buffer sf_count_t n = sf_writef_float(sfDst, outBuffer, data.output_frames_gen); if (n != data.output_frames_gen) { - printf("sound write failed: returns %lld, should return %ld\n", + printf("sound write failed: returns %lld, should return %ld\n", n, data.output_frames_gen); returnValue = false; break; @@ -220,7 +220,7 @@ static bool copyWaveFileToProject(const QString& path) // write buffer nn = sf_writef_float(sfDst, buffer, n); if (n != nn) { - printf("sound write failed: returns %lld, should return %lld\n", + printf("sound write failed: returns %lld, should return %lld\n", nn, n); returnValue = false; break; -- cgit v1.2.3