diff options
author | Robert Jonsson <spamatica@gmail.com> | 2010-10-13 19:34:22 +0000 |
---|---|---|
committer | Robert Jonsson <spamatica@gmail.com> | 2010-10-13 19:34:22 +0000 |
commit | 8a2c2824a59d7644e13bc52c9a0ecbd641f21f95 (patch) | |
tree | 064ad3f2bf8daab0ad27b128abd86a9bbdb1e496 /muse2/muse/ctrl | |
parent | a27706d9629e8b592cca4659f865b70adef24e6d (diff) |
new branch muse2, first checkin
Diffstat (limited to 'muse2/muse/ctrl')
-rw-r--r-- | muse2/muse/ctrl/Makefile.am | 17 | ||||
-rw-r--r-- | muse2/muse/ctrl/Makefile.in | 604 | ||||
-rw-r--r-- | muse2/muse/ctrl/ctrlcanvas.cpp | 1533 | ||||
-rw-r--r-- | muse2/muse/ctrl/ctrlcanvas.h | 165 | ||||
-rw-r--r-- | muse2/muse/ctrl/ctrledit.cpp | 134 | ||||
-rw-r--r-- | muse2/muse/ctrl/ctrledit.h | 56 | ||||
-rw-r--r-- | muse2/muse/ctrl/ctrlpanel.cpp | 694 | ||||
-rw-r--r-- | muse2/muse/ctrl/ctrlpanel.h | 66 |
8 files changed, 3269 insertions, 0 deletions
diff --git a/muse2/muse/ctrl/Makefile.am b/muse2/muse/ctrl/Makefile.am new file mode 100644 index 00000000..3aac8577 --- /dev/null +++ b/muse2/muse/ctrl/Makefile.am @@ -0,0 +1,17 @@ +include $(top_srcdir)/common.am + +if PCH +AM_CXXFLAGS += -include $(top_srcdir)/all.h +endif + +noinst_LIBRARIES = libctrl.a + +dist_libctrl_a_SOURCES = \ + ctrledit.cpp ctrledit.h \ + ctrlcanvas.cpp ctrlcanvas.h \ + ctrlpanel.cpp ctrlpanel.h + +nodist_libctrl_a_SOURCES = \ + moc_ctrledit.cpp \ + moc_ctrlcanvas.cpp \ + moc_ctrlpanel.cpp diff --git a/muse2/muse/ctrl/Makefile.in b/muse2/muse/ctrl/Makefile.in new file mode 100644 index 00000000..09912657 --- /dev/null +++ b/muse2/muse/ctrl/Makefile.in @@ -0,0 +1,604 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/common.am +@PCH_TRUE@am__append_1 = -include $(top_srcdir)/all.h +subdir = muse/ctrl +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/aclocal-include.m4 \ + $(top_srcdir)/m4/alsa.m4 $(top_srcdir)/m4/docbook.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libctrl_a_AR = $(AR) $(ARFLAGS) +libctrl_a_LIBADD = +dist_libctrl_a_OBJECTS = ctrledit.$(OBJEXT) ctrlcanvas.$(OBJEXT) \ + ctrlpanel.$(OBJEXT) +nodist_libctrl_a_OBJECTS = moc_ctrledit.$(OBJEXT) \ + moc_ctrlcanvas.$(OBJEXT) moc_ctrlpanel.$(OBJEXT) +libctrl_a_OBJECTS = $(dist_libctrl_a_OBJECTS) \ + $(nodist_libctrl_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(dist_libctrl_a_SOURCES) $(nodist_libctrl_a_SOURCES) +DIST_SOURCES = $(dist_libctrl_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALSA_CFLAGS = @ALSA_CFLAGS@ +ALSA_LIBS = @ALSA_LIBS@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DOCBOOKSTYLE = @DOCBOOKSTYLE@ +DOCBOOKTARGETS = @DOCBOOKTARGETS@ +DOT = @DOT@ +DOTPATH = @DOTPATH@ +DOXYGEN = @DOXYGEN@ +DOXYGEN_TREEVIEW = @DOXYGEN_TREEVIEW@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FLUIDSYNTHDIRS = @FLUIDSYNTHDIRS@ +FST_CFLAGS = @FST_CFLAGS@ +FST_LIBS = @FST_LIBS@ +Fluidsynth_CFLAGS = @Fluidsynth_CFLAGS@ +Fluidsynth_LIBS = @Fluidsynth_LIBS@ +GIVERTCAP = @GIVERTCAP@ +GREP = @GREP@ +HAVEDOT = @HAVEDOT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JACK_CFLAGS = @JACK_CFLAGS@ +JACK_LIBS = @JACK_LIBS@ +JADE = @JADE@ +LASH_CFLAGS = @LASH_CFLAGS@ +LASH_LIBS = @LASH_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LO_CFLAGS = @LO_CFLAGS@ +LO_LIBS = @LO_LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MUSECXXFLAGS = @MUSECXXFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NSGMLS = @NSGMLS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PCH = @PCH@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_INCLUDES = @PYTHON_INCLUDES@ +PYTHON_LIB = @PYTHON_LIB@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +QTDIR_BIN = @QTDIR_BIN@ +QTDIR_INC = @QTDIR_INC@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +SAMPLERATE_CFLAGS = @SAMPLERATE_CFLAGS@ +SAMPLERATE_LIBS = @SAMPLERATE_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNDFILE_CFLAGS = @SNDFILE_CFLAGS@ +SNDFILE_LIBS = @SNDFILE_LIBS@ +STRIP = @STRIP@ +SUIDBUILD = @SUIDBUILD@ +SUIDINSTALL = @SUIDINSTALL@ +USE_SSE = @USE_SSE@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +have_docbook = @have_docbook@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +synth_fluid = @synth_fluid@ +synth_fluidsynth = @synth_fluidsynth@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CXXFLAGS = $(MUSECXXFLAGS) -I.. -I$(top_srcdir)/synti \ + -I$(top_srcdir)/muse/widgets -DQT_SHARED -DQT_THREAD_SUPPORT \ + -DQT_PLUGIN $(QTDIR_INC) -DQT3_SUPPORT $(am__append_1) +AM_CPPFLAGS = +MOC = $(QTDIR_BIN)/moc +#UIC = $(QTDIR_BIN)/uic3 +UIC = /usr/bin/uic3 +UIFILES = $(wildcard *.ui) +MOCFILES = $(shell for h in $(filter %.h,$(SOURCES)); do \ + if grep -q Q_OBJECT $$h; then \ + echo $$h | sed "s/\(.*\)\.h/moc_\1.cpp/"; \ + fi; \ + done) + +BUILT_SOURCES = $(MOCFILES) $(UIFILES:%.ui=%.h) +MOSTLYCLEANFILES = $(MOCFILES) $(UIFILES:%.ui=%.h) +SUFFIXES = .ui .h.gch +noinst_LIBRARIES = libctrl.a +dist_libctrl_a_SOURCES = \ + ctrledit.cpp ctrledit.h \ + ctrlcanvas.cpp ctrlcanvas.h \ + ctrlpanel.cpp ctrlpanel.h + +nodist_libctrl_a_SOURCES = \ + moc_ctrledit.cpp \ + moc_ctrlcanvas.cpp \ + moc_ctrlpanel.cpp + +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .ui .h.gch .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/common.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu muse/ctrl/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu muse/ctrl/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libctrl.a: $(libctrl_a_OBJECTS) $(libctrl_a_DEPENDENCIES) + -rm -f libctrl.a + $(libctrl_a_AR) libctrl.a $(libctrl_a_OBJECTS) $(libctrl_a_LIBADD) + $(RANLIB) libctrl.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctrlcanvas.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctrledit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctrlpanel.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/moc_ctrlcanvas.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/moc_ctrledit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/moc_ctrlpanel.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: all check install install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +de: + @for base in $(MOCFILES); do echo -e "\t$${base}.cpp $${base}.h \\"; done + +nde: + @for base in $(MOCFILES); do echo -e "\tmoc_$${base}.cpp \\"; done + +.ui.o: %.h + $(UIC) -L $(top_srcdir)/muse/widgets -o $*.cpp -impl $*.h $*.ui + $(MOC) $*.h >> $*.cpp + $(CXXCOMPILE) -c $*.cpp -o $*.o + $(RM) $*.cpp moc_$*.cpp moc_$*.o + +.ui.lo: %.h + $(UIC) -L $(top_srcdir)/muse/widgets -o $*.cpp -impl $*.h $*.ui + $(MOC) $*.h >> $*.cpp + $(LTCXXCOMPILE) -c $*.cpp -o $*.lo + $(RM) $*.cpp moc_$*.cpp moc_$*.lo moc_$*.o + +moc_%.cpp: %.h + $(MOC) $< -o $@ + +%.h: %.ui + $(UIC) -o $@ $< +# $(UIC) -L $(top_srcdir)/muse/widgets -o $@ $< + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/muse2/muse/ctrl/ctrlcanvas.cpp b/muse2/muse/ctrl/ctrlcanvas.cpp new file mode 100644 index 00000000..6a7e0720 --- /dev/null +++ b/muse2/muse/ctrl/ctrlcanvas.cpp @@ -0,0 +1,1533 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: ctrlcanvas.cpp,v 1.15.2.10 2009/11/14 03:37:48 terminator356 Exp $ +// (C) Copyright 1999 Werner Schweer (ws@seh.de) +//========================================================= + +#include <stdio.h> +#include <values.h> + +#include <qlayout.h> +#include <qpainter.h> +#include <qtoolbutton.h> +#include <q3popupmenu.h> +#include <qlabel.h> +#include <qcursor.h> +//Added by qt3to4: +#include <QMouseEvent> +#include <QEvent> + +#include "globals.h" +#include "ctrledit.h" +#include "midieditor.h" +#include "icons.h" +#include "midiport.h" +#include "song.h" +#include "midictrl.h" +#include "audio.h" +#include "gconfig.h" +#include "ctrlpanel.h" +#include "midiedit/drummap.h" + +extern void drawTickRaster(QPainter& p, int x, int y, + int w, int h, int quant); + +static MidiCtrlValList veloList(CTRL_VELOCITY); // dummy + +//--------------------------------------------------------- +// computeVal +//--------------------------------------------------------- + +static int computeVal(MidiController* mc, int y, int height) + { + int min; int max; + if(mc->num() == CTRL_PROGRAM) + { + min = 1; + max = 128; + } + else + { + min = mc->minVal(); + max = mc->maxVal(); + } + int val = max - (y * (max-min) / height); + if (val < min) + val = min; + if (val > max) + val = max; + if(mc->num() != CTRL_PROGRAM) + val += mc->bias(); + return val; + } + +//--------------------------------------------------------- +// CEvent +//--------------------------------------------------------- + +CEvent::CEvent(Event e, MidiPart* pt, int v) + { + _event = e; + _part = pt; + _val = v; + ex = !e.empty() ? e.tick() : 0; + } + +//--------------------------------------------------------- +// contains +//--------------------------------------------------------- + +bool CEvent::contains(int x1, int x2) const + { + int tick1 = !_event.empty() ? _event.tick() + _part->tick() : 0; + if(ex == -1) + return (tick1 < x2); + + int tick2 = ex + _part->tick(); + return ((tick1 >= x1 && tick1 < x2) + //|| (tick2 >= x1 && tick2 < x2) + || (tick2 > x1 && tick2 < x2) + || (tick1 < x1 && tick2 >= x2)); + } + +//--------------------------------------------------------- +// clearDelete +//--------------------------------------------------------- + +void CEventList::clearDelete() +{ + for(ciCEvent i = begin(); i != end(); ++i) + { + CEvent* ce = *i; + if(ce) + delete ce; + } + clear(); +} + +//--------------------------------------------------------- +// CtrlCanvas +//--------------------------------------------------------- + +CtrlCanvas::CtrlCanvas(MidiEditor* e, QWidget* parent, int xmag, + const char* name, CtrlPanel* pnl) : View(parent, xmag, 1, name) + { + setBg(Qt::white); + editor = e; + drag = DRAG_OFF; + tool = PointerTool; + pos[0] = 0; + pos[1] = 0; + pos[2] = 0; + noEvents=false; + + ctrl = &veloList; + _controller = &veloCtrl; + _panel = pnl; + _cnum = CTRL_VELOCITY; + _dnum = CTRL_VELOCITY; + _didx = CTRL_VELOCITY; + connect(song, SIGNAL(posChanged(int, unsigned, bool)), this, SLOT(setPos(int, unsigned, bool))); + + setMouseTracking(true); + if (editor->parts()->empty()) { + curPart = 0; + curTrack = 0; + } + else { + setCurTrackAndPart(); + } + connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int))); + + curDrumInstrument = editor->curDrumInstrument(); + //printf("CtrlCanvas::CtrlCanvas curDrumInstrument:%d\n", curDrumInstrument); + + connect(editor, SIGNAL(curDrumInstrumentChanged(int)), SLOT(setCurDrumInstrument(int))); + updateItems(); + } + +//--------------------------------------------------------- +// setPos +// set one of three markers +// idx - 0-cpos 1-lpos 2-rpos +// flag - emit followEvent() +//--------------------------------------------------------- + +void CtrlCanvas::setPos(int idx, unsigned val, bool adjustScrollbar) + { + if (pos[idx] == val) + return; + + int opos = mapx(pos[idx]); + int npos = mapx(val); + + if (adjustScrollbar && idx == 0) { + switch (song->follow()) { + case Song::NO: + break; + case Song::JUMP: + if (npos >= width()) { + int ppos = val - rmapxDev(width()/4); + if (ppos < 0) + ppos = 0; + emit followEvent(ppos); + opos = mapx(pos[idx]); + npos = mapx(val); + } + else if (npos < 0) { + int ppos = val - rmapxDev(width()*3/4); + if (ppos < 0) + ppos = 0; + emit followEvent(ppos); + opos = mapx(pos[idx]); + npos = mapx(val); + } + break; + case Song::CONTINUOUS: + if (npos > (width()*5)/8) { + int ppos = pos[idx] - rmapxDev(width()*5/8); + if (ppos < 0) + ppos = 0; + emit followEvent(ppos); + opos = mapx(pos[idx]); + npos = mapx(val); + } + else if (npos < (width()*3)/8) { + int ppos = pos[idx] - rmapxDev(width()*3/8); + if (ppos < 0) + ppos = 0; + emit followEvent(ppos); + opos = mapx(pos[idx]); + npos = mapx(val); + } + break; + } + } + + int x; + int w = 1; + if (opos > npos) { + w += opos - npos; + x = npos; + } + else { + w += npos - opos; + x = opos; + } + pos[idx] = val; + redraw(QRect(x, 0, w, height())); + } + +//--------------------------------------------------------- +// setMidiController +//--------------------------------------------------------- + +void CtrlCanvas::setMidiController(int num) + { + _cnum = num; + partControllers(curPart, _cnum, &_dnum, &_didx, &_controller, &ctrl); + if(_panel) + { + if(_cnum == CTRL_VELOCITY) + _panel->setHWController(curTrack, &veloCtrl); + else + _panel->setHWController(curTrack, _controller); + } + } + +//--------------------------------------------------------- +// leaveEvent +//--------------------------------------------------------- + +void CtrlCanvas::leaveEvent(QEvent*) + { + emit xposChanged(MAXINT); + emit yposChanged(-1); + } + +//--------------------------------------------------------- +// raster +//--------------------------------------------------------- + +QPoint CtrlCanvas::raster(const QPoint& p) const + { + return p; + } + +//--------------------------------------------------------- +// deselectAll +//--------------------------------------------------------- + +void CtrlCanvas::deselectAll() + { +// for (iCEvent i = selection.begin(); i != selection.end(); ++i) +// (*i)->setState(CEvent::Normal); +// selection.clear(); +// update(); + } + +//--------------------------------------------------------- +// selectItem +//--------------------------------------------------------- + +void CtrlCanvas::selectItem(CEvent*) + { +// e->setState(CEvent::Selected); +// selection.push_back(e); +// update(); + } + +//--------------------------------------------------------- +// deselectItem +//--------------------------------------------------------- + +void CtrlCanvas::deselectItem(CEvent*) + { +/* e->setState(CEvent::Normal); + for (iCEvent i = selection.begin(); i != selection.end(); ++i) { + if (*i == e) { + selection.erase(i); + break; + } + } + update(); + */ + } + +//--------------------------------------------------------- +// setController +//--------------------------------------------------------- + +void CtrlCanvas::setController(int num) +{ + setMidiController(num); + updateItems(); +} + + +//--------------------------------------------------------- +// setCurTrackAndPart +//--------------------------------------------------------- + +bool CtrlCanvas::setCurTrackAndPart() +{ + bool changed = false; + MidiPart* part = 0; + MidiTrack* track = 0; + + if(!editor->parts()->empty()) + { + Part* pt = editor->curCanvasPart(); + if(pt && pt->track()) + { + if(pt->track()->isMidiTrack()) + { + part = (MidiPart*)pt; + track = part->track(); + } + } + } + + if(part != curPart) + { + curPart = part; + changed = true; + } + + if(track != curTrack) + { + curTrack = track; + changed = true; + } + + return changed; +} + +//--------------------------------------------------------- +// songChanged +// all marked parts are added to the internal event list +//--------------------------------------------------------- + +void CtrlCanvas::songChanged(int type) +{ + // Is it simply a midi controller value adjustment? Forget it. + if(type == SC_MIDI_CONTROLLER) + return; + + bool changed = false; + if(type & (SC_CONFIG | SC_PART_MODIFIED | SC_SELECTION)) + changed = setCurTrackAndPart(); + + // Although changing the instrument/device in the + // config window generates a type of -1, we can eliminate + // some other useless calls using SC_CONFIG, which was not used + // anywhere else in muse before now, except song header. + if((type & (SC_CONFIG | SC_DRUMMAP)) || ((type & (SC_PART_MODIFIED | SC_SELECTION)) && changed)) + { + setMidiController(_cnum); + //return; + } + + updateItems(); + +} + +//--------------------------------------------------------- +// partControllers +//--------------------------------------------------------- + +void CtrlCanvas::partControllers(const MidiPart* part, int num, int* dnum, int* didx, MidiController** mc, MidiCtrlValList** mcvl) +{ + if(num == CTRL_VELOCITY) // special case + { + if(mcvl) + *mcvl = &veloList; + if(mc) + *mc = &veloCtrl; + if(dnum) + *dnum = num; + if(didx) + *didx = num; + } + else + { + MidiTrack* mt = part->track(); + MidiPort* mp; + int di; + int n; + + if((mt->type() != Track::DRUM) && curDrumInstrument != -1) + printf("keyfilter != -1 in non drum track?\n"); + + if((mt->type() == Track::DRUM) && (curDrumInstrument != -1) && ((num & 0xff) == 0xff)) + { + di = (num & ~0xff) | curDrumInstrument; + n = (num & ~0xff) | drumMap[curDrumInstrument].anote; // construct real controller number + //num = (num & ~0xff) | curDrumInstrument); // construct real controller number + mp = &midiPorts[drumMap[curDrumInstrument].port]; + } + else + { + di = num; + n = num; + mp = &midiPorts[mt->outPort()]; + } + + if(dnum) + *dnum = n; + + if(didx) + *didx = di; + + if(mc) + *mc = mp->midiController(n); + + if(mcvl) + { + MidiCtrlValList* tmcvl = 0; + MidiCtrlValListList* cvll = mp->controller(); + for(iMidiCtrlValList i = cvll->begin(); i != cvll->end(); ++i) + { + if(i->second->num() == n) + { + tmcvl = i->second; + break; + } + } + *mcvl = tmcvl; + + // Removed by T356. + // MidiCtrlValList not found is now an acceptable state (for multiple part editing). + //if (i == cvll->end()) { + // printf("CtrlCanvas::setController(0x%x): not found\n", num); + // for (i = cvll->begin(); i != cvll->end(); ++i) + // printf(" 0x%x\n", i->second->num()); + // return; + // } + } + } +} + +//--------------------------------------------------------- +// updateItems +//--------------------------------------------------------- + +void CtrlCanvas::updateItems() + { + items.clearDelete(); + + /* + if(ctrl) + { + for(ciMidiCtrlVal imcv = ctrl->begin(); imcv != ctrl->end(); ++imcv) + { + MidiPart* part = (MidiPart*)imcv->part; + int val = imcv->val; + + bool edpart = false; + if(editor->parts()->index(part) != -1) + edpart = true; + + MidiController* mc; + MidiCtrlValList* mcvl; + partControllers(part, _cnum, 0, 0, &mc, &mcvl); + + Event e(Controller); + + if(_cnum == CTRL_VELOCITY && e.type() == Note) + { + items.add(new CEvent(e, part, e.velo())); + + } + + } + } + */ + + /* + MidiTrackList* mtl = song->midis(); + for(ciMidiTrack imt = mtl->begin(); imt != mtl->end(); ++imt) + { + //MidiTrack* mt = *imt; + PartList* pl = (*imt)->parts(); + for(ciPart p = pl->begin(); p != pl->end(); ++p) + { + MidiPart* part = (MidiPart*)(p->second); + + bool edpart = false; + if(editor->parts()->index(part) != -1) + edpart = true; + + EventList* el = part->events(); + MidiController* mc; + MidiCtrlValList* mcvl; + partControllers(part, _cnum, 0, 0, &mc, &mcvl); + + for(iEvent i = el->begin(); i != el->end(); ++i) + { + Event e = i->second; + if(_cnum == CTRL_VELOCITY && e.type() == Note) + { + if(curDrumInstrument == -1) + { + items.add(new CEvent(e, part, e.velo())); + } + else if (e.dataA() == curDrumInstrument) //same note + items.add(new CEvent(e, part, e.velo())); + } + else if (e.type() == Controller && e.dataA() == _didx) + { + if(mcvl && last.empty()) + { + Event le(Controller); + //le.setType(Controller); + le.setA(_didx); + //le.setB(e.dataB()); + le.setB(CTRL_VAL_UNKNOWN); + //lastce = new CEvent(Event(), part, mcvl->value(part->tick(), part)); + //lastce = new CEvent(le, part, mcvl->value(part->tick(), part)); + lastce = new CEvent(le, part, mcvl->value(part->tick())); + items.add(lastce); + } + if (lastce) + lastce->setEX(e.tick()); + lastce = new CEvent(e, part, e.dataB()); + items.add(lastce); + last = e; + } + } + } + } + */ + + + + + + if(!editor->parts()->empty()) + { + //Event last; + //CEvent* lastce = 0; + + for (iPart p = editor->parts()->begin(); p != editor->parts()->end(); ++p) + { + Event last; + CEvent* lastce = 0; + + MidiPart* part = (MidiPart*)(p->second); + EventList* el = part->events(); + MidiController* mc; + MidiCtrlValList* mcvl; + partControllers(part, _cnum, 0, 0, &mc, &mcvl); + unsigned len = part->lenTick(); + + for (iEvent i = el->begin(); i != el->end(); ++i) + { + Event e = i->second; + // Added by T356. Do not add events which are past the end of the part. + if(e.tick() >= len) + break; + + if(_cnum == CTRL_VELOCITY && e.type() == Note) + { + //printf("CtrlCanvas::updateItems CTRL_VELOCITY curDrumInstrument:%d\n", curDrumInstrument); + if(curDrumInstrument == -1) + { + // This is interesting - it would allow ALL drum note velocities to be shown. + // But currently the drum list ALWAYS has a selected item so this is not supposed to happen. + items.add(new CEvent(e, part, e.velo())); + } + else if (e.dataA() == curDrumInstrument) //same note + items.add(new CEvent(e, part, e.velo())); + } + else if (e.type() == Controller && e.dataA() == _didx) + { + if(mcvl && last.empty()) + { + lastce = new CEvent(Event(), part, mcvl->value(part->tick())); + items.add(lastce); + } + if (lastce) + lastce->setEX(e.tick()); + lastce = new CEvent(e, part, e.dataB()); + lastce->setEX(-1); + items.add(lastce); + last = e; + } + } + } + } + + + redraw(); + } + +//--------------------------------------------------------- +// viewMousePressEvent +//--------------------------------------------------------- + +void CtrlCanvas::viewMousePressEvent(QMouseEvent* event) + { + start = event->pos(); + Tool activeTool = tool; + bool shift = event->state() & Qt::ShiftButton; + + int xpos = start.x(); + int ypos = start.y(); + + MidiController::ControllerType type = midiControllerType(_controller->num()); + + switch (activeTool) { + case PointerTool: + drag = DRAG_LASSO_START; + break; + + case PencilTool: + if (shift) { + if (type != MidiController::Velo) { + drag = DRAG_NEW; + song->startUndo(); + newVal(xpos, xpos, ypos); + } + } + else { + drag = DRAG_RESIZE; + song->startUndo(); + changeVal(xpos, xpos, ypos); + } + break; + + case RubberTool: + if (type != MidiController::Velo) { + drag = DRAG_DELETE; + song->startUndo(); + deleteVal(xpos, xpos, ypos); + } + break; + + case DrawTool: + if (drawLineMode) { + line2x = xpos; + line2y = ypos; + if (shift) + newValRamp(line1x, line1y, line2x, line2y); + else + changeValRamp(line1x, line1y, line2x, line2y); + drawLineMode = false; + } + else { + line2x = line1x = xpos; + line2y = line1y = ypos; + drawLineMode = true; + } + redraw(); + break; + + default: + break; + } + } + +//--------------------------------------------------------- +// newValRamp +//--------------------------------------------------------- + +void CtrlCanvas::newValRamp(int x1, int y1, int x2, int y2) + { + int xx1 = editor->rasterVal1(x1); + int xx2 = editor->rasterVal2(x2); + int type = _controller->num(); + + int raster = editor->raster(); + if (raster == 1) // set reasonable raster + raster = config.division/4; + + song->startUndo(); + + // delete existing events + + int lastpv = CTRL_VAL_UNKNOWN; + for (ciCEvent i = items.begin(); i != items.end(); ++i) { + CEvent* ev = *i; + if(ev->part() != curPart) + continue; + Event event = ev->event(); + if (event.empty()) + continue; + int x = event.tick() + curPart->tick(); + // Added by Tim. p3.3.6 + //printf("CtrlCanvas::newValRamp x:%d xx1:%d xx2:%d len:%d\n", x, xx1, xx2, curPart->lenTick()); + + if (x < xx1) + { + // if(event.dataB() != CTRL_VAL_UNKNOWN) + // lastpv = event.dataB(); + continue; + } + //if (x <= xx1) + //{ + // if(type == CTRL_PROGRAM && event.dataB() != CTRL_VAL_UNKNOWN && ((event.dataB() & 0xffffff) != 0xffffff)) + // lastpv = event.dataB(); + // if (x < xx1) + // continue; + //} + if (x >= xx2) + break; + + // Indicate no undo, and do port controller values and clone parts. + //audio->msgDeleteEvent(event, ev->part(), false); + audio->msgDeleteEvent(event, curPart, false, true, true); + } + + //if(type == CTRL_PROGRAM && lastpv == CTRL_VAL_UNKNOWN) + if(ctrl) + lastpv = ctrl->hwVal(); + + // insert new events + for (int x = xx1; x < xx2; x += raster) { + int y = (x2==x1) ? y1 : (((y2-y1)*(x-x1))/(x2-x1))+y1; + int nval = computeVal(_controller, y, height()); + int tick = x - curPart->tick(); + // Do not add events which are past the end of the part. + if((unsigned)tick >= curPart->lenTick()) + break; + Event event(Controller); + event.setTick(tick); + event.setA(_didx); + if(type == CTRL_PROGRAM) + { + if(lastpv == CTRL_VAL_UNKNOWN) + { + if(song->mtype() == MT_GM) + event.setB(0xffff00 | (nval - 1)); + else + event.setB(nval - 1); + } + else + event.setB((lastpv & 0xffff00) | (nval - 1)); + } + else + event.setB(nval); + + // Indicate no undo, and do port controller values and clone parts. + //audio->msgAddEvent(event, curPart, false); + audio->msgAddEvent(event, curPart, false, true, true); + } + + song->update(0); + redraw(); + song->endUndo(SC_EVENT_MODIFIED | SC_EVENT_INSERTED | SC_EVENT_REMOVED); + } + +//--------------------------------------------------------- +// changeValRamp +//--------------------------------------------------------- + +void CtrlCanvas::changeValRamp(int x1, int y1, int x2, int y2) + { + int h = height(); + bool changed = false; + int type = _controller->num(); + //int xx1 = editor->rasterVal1(x1); + + song->startUndo(); + for (ciCEvent i = items.begin(); i != items.end(); ++i) { + if ((*i)->contains(x1, x2)) { + //if ((*i)->contains(xx1, x2)) { + CEvent* ev = *i; + if(ev->part() != curPart) + continue; + Event event = ev->event(); + if (event.empty()) + continue; + + //MidiPart* part = ev->part(); + //int x = event.tick() + ev->part()->tick(); + int x = event.tick() + curPart->tick(); + int y = (x2==x1) ? y1 : (((y2-y1)*(x-x1))/(x2-x1))+y1; + int nval = computeVal(_controller, y, h); + if(type == CTRL_PROGRAM) + { + if(event.dataB() == CTRL_VAL_UNKNOWN) + { + --nval; + if(song->mtype() == MT_GM) + nval |= 0xffff00; + } + else + nval = (event.dataB() & 0xffff00) | (nval - 1); + } + + ev->setVal(nval); + + //MidiController::ControllerType type = midiControllerType(_controller->num()); + //if (type == MidiController::Velo) { + if (type == CTRL_VELOCITY) { + if ((event.velo() != nval)) { + Event newEvent = event.clone(); + newEvent.setVelo(nval); + // Indicate no undo, and do not do port controller values and clone parts. + //audio->msgChangeEvent(event, newEvent, part, false); + audio->msgChangeEvent(event, newEvent, curPart, false, false, false); + ev->setEvent(newEvent); + changed = true; + } + } + else { + if (!event.empty()) { + if ((event.dataB() != nval)) { + Event newEvent = event.clone(); + newEvent.setB(nval); + // Indicate no undo, and do port controller values and clone parts. + //audio->msgChangeEvent(event, newEvent, part, false); + audio->msgChangeEvent(event, newEvent, curPart, false, true, true); + ev->setEvent(newEvent); + changed = true; + } + } + else { + //if(!ctrl) + //{ + // ctrl = + //} + + // Removed by T356. Never gets here? A good thing, don't wan't auto-create values. + //int oval = ctrl->value(0); + //if (oval != nval) { + // Changed by T356. + //ctrl->add(0, nval); + // ctrl->add(0, nval, part); + // changed = true; + // } + + } + } + } + } + if (changed) + redraw(); + song->endUndo(SC_EVENT_MODIFIED); + } + +//--------------------------------------------------------- +// viewMouseMoveEvent +//--------------------------------------------------------- + +void CtrlCanvas::viewMouseMoveEvent(QMouseEvent* event) + { + QPoint pos = event->pos(); + QPoint dist = pos - start; + bool moving = dist.y() >= 3 || dist.y() <= 3 || dist.x() >= 3 || dist.x() <= 3; + switch (drag) { + case DRAG_LASSO_START: + if (!moving) + break; + drag = DRAG_LASSO; + // weiter mit DRAG_LASSO: + case DRAG_LASSO: + lasso.setRect(start.x(), start.y(), dist.x(), dist.y()); + redraw(); + break; + case DRAG_RESIZE: + changeVal(start.x(), pos.x(), pos.y()); + start = pos; + break; + + case DRAG_NEW: + newVal(start.x(), pos.x(), pos.y()); + start = pos; + break; + + case DRAG_DELETE: + deleteVal(start.x(), pos.x(), pos.y()); + start = pos; + break; + + default: + break; + } + if (tool == DrawTool && drawLineMode) { + line2x = pos.x(); + line2y = pos.y(); + redraw(); + } + emit xposChanged(pos.x()); + + + int val = computeVal(_controller, pos.y(), height()); + emit yposChanged(val); + } + +//--------------------------------------------------------- +// viewMouseReleaseEvent +//--------------------------------------------------------- + +void CtrlCanvas::viewMouseReleaseEvent(QMouseEvent* event) + { + bool shift = event->state() & Qt::ShiftButton; + + switch (drag) { + case DRAG_RESIZE: + case DRAG_NEW: + case DRAG_DELETE: + song->endUndo(SC_EVENT_MODIFIED | SC_EVENT_INSERTED); + break; + + case DRAG_LASSO_START: + lasso.setRect(-1, -1, -1, -1); + + case DRAG_LASSO: + if (!shift) + deselectAll(); + lasso = lasso.normalize(); + for (iCEvent i = items.begin(); i != items.end(); ++i) { +#if 0 + if ((*i)->intersects(lasso)) { + if (shift && (*i)->isSelected()) + deselectItem(*i); + else + selectItem(*i); + } +#endif + } + drag = DRAG_OFF; + redraw(); + break; + + default: + break; + } + drag = DRAG_OFF; + } + +//--------------------------------------------------------- +// changeVal +//--------------------------------------------------------- + +void CtrlCanvas::changeVal(int x1, int x2, int y) + { + bool changed = false; + int newval = computeVal(_controller, y, height()); + int type = _controller->num(); + //int xx1 = editor->rasterVal1(x1); + + for (ciCEvent i = items.begin(); i != items.end(); ++i) { + if (!(*i)->contains(x1, x2)) + //if (!(*i)->contains(xx1, x2)) + continue; + CEvent* ev = *i; + if(ev->part() != curPart) + continue; + Event event = ev->event(); + //if(event.tick() >= curPart->lenTick()) + // break; + + //MidiPart* part = ev->part(); + //int nval = newval; + //if(type == CTRL_PROGRAM) + //{ + // if(event.dataB() == CTRL_VAL_UNKNOWN) + // { + // --nval; + // if(song->mtype() == MT_GM) + // nval |= 0xffff00; + // } + // else + // nval = (event.dataB() & 0xffff00) | (nval - 1); + //} + //ev->setVal(nval); + + //MidiController::ControllerType type = midiControllerType(_controller->num()); + //if (type == MidiController::Velo) { + if (type == CTRL_VELOCITY) { + if ((event.velo() != newval)) { + ev->setVal(newval); + Event newEvent = event.clone(); + newEvent.setVelo(newval); + // Indicate no undo, and do not do port controller values and clone parts. + //audio->msgChangeEvent(event, newEvent, part, false); + audio->msgChangeEvent(event, newEvent, curPart, false, false, false); + ev->setEvent(newEvent); + changed = true; + } + } + else { + if (!event.empty()) { + int nval = newval; + if(type == CTRL_PROGRAM) + { + if(event.dataB() == CTRL_VAL_UNKNOWN) + { + --nval; + if(song->mtype() == MT_GM) + nval |= 0xffff00; + } + else + nval = (event.dataB() & 0xffff00) | (nval - 1); + } + ev->setVal(nval); + + if ((event.dataB() != nval)) { + Event newEvent = event.clone(); + newEvent.setB(nval); + // Indicate no undo, and do port controller values and clone parts. + //audio->msgChangeEvent(event, newEvent, part, false); + audio->msgChangeEvent(event, newEvent, curPart, false, true, true); + ev->setEvent(newEvent); + changed = true; + } + } + else { + //if(!ctrl) + //{ + // ctrl = + //} + + // Removed by T356. Never gets here? A good thing, don't wan't auto-create values. + //int oval = ctrl->value(0); + //if (oval != nval) { + // Changed by T356. + //ctrl->add(0, nval); + // ctrl->add(0, nval, part); + // changed = true; + // } + } + } + } + if (changed) + redraw(); + } + +//--------------------------------------------------------- +// newVal +//--------------------------------------------------------- + +void CtrlCanvas::newVal(int x1, int x2, int y) + { + int xx1 = editor->rasterVal1(x1); + int xx2 = editor->rasterVal2(x2); + int newval = computeVal(_controller, y, height()); + int type = _controller->num(); + + bool found = false; + bool song_changed = false; + + int lastpv = CTRL_VAL_UNKNOWN; + if(ctrl) + lastpv = ctrl->hwVal(); + + for (ciCEvent i = items.begin(); i != items.end(); ++i) { + CEvent* ev = *i; + if(ev->part() != curPart) + continue; + //int partTick = ev->part()->tick(); + int partTick = curPart->tick(); + Event event = ev->event(); + if (event.empty()) + continue; + int ax = event.tick() + partTick; + // Added by Tim. p3.3.6 + //printf("CtrlCanvas::newVal ax:%d xx1:%d xx2:%d len:%d\n", ax, xx1, xx2, curPart->lenTick()); + + if (ax < xx1) + continue; + //if(ax <= xx1) + //{ + // if(type == CTRL_PROGRAM && event.dataB() != CTRL_VAL_UNKNOWN && ((event.dataB() & 0xffffff) != 0xffffff)) + // lastpv = event.dataB(); + // if(ax < xx1) + // continue; + //} + if (ax >= xx2) + break; + + // Added by T356. Do not add events which are past the end of the part. + //if(event.tick() >= curPart->lenTick()) + // break; + + int nval = newval; + if(type == CTRL_PROGRAM) + { + if(event.dataB() == CTRL_VAL_UNKNOWN) + { + //if(lastpv == CTRL_VAL_UNKNOWN) + // lastpv = ctrl->hwVal(); + + if(lastpv == CTRL_VAL_UNKNOWN) + { + --nval; + if(song->mtype() == MT_GM) + nval |= 0xffff00; + } + else + nval = (lastpv & 0xffff00) | (nval - 1); + } + else + nval = (event.dataB() & 0xffff00) | (nval - 1); + } + + if (ax == xx1) { + // change event + found = true; + ev->setVal(nval); + if ((event.dataB() != nval)) { + Event newEvent = event.clone(); + newEvent.setB(nval); + // Added by Tim. p3.3.6 + //printf("CtrlCanvas::newVal change xx1:%d xx2:%d len:%d\n", xx1, xx2, curPart->lenTick()); + + // Indicate no undo, and do port controller values and clone parts. + //audio->msgChangeEvent(event, newEvent, ev->part(), false); + audio->msgChangeEvent(event, newEvent, curPart, false, true, true); + + ev->setEvent(newEvent); + song_changed = true; + } + } + else if (ax < xx2) { + // delete event + // Added by Tim. p3.3.6 + //printf("CtrlCanvas::newVal delete xx1:%d xx2:%d len:%d\n", xx1, xx2, curPart->lenTick()); + + // Indicate no undo, and do port controller values and clone parts. + //audio->msgDeleteEvent(event, ev->part(), false); + audio->msgDeleteEvent(event, curPart, false, true, true); + + song_changed = true; + } + } + if (!found) { + // new event + int tick = xx1 - curPart->tick(); + // Do not add events which are past the end of the part. + if((unsigned)tick < curPart->lenTick()) + { + Event event(Controller); + event.setTick(tick); + event.setA(_didx); + if(type == CTRL_PROGRAM) + { + if(lastpv == CTRL_VAL_UNKNOWN) + { + if(song->mtype() == MT_GM) + event.setB(0xffff00 | (newval - 1)); + else + event.setB(newval - 1); + } + else + event.setB((lastpv & 0xffff00) | (newval - 1)); + } + else + event.setB(newval); + + // Indicate no undo, and do port controller values and clone parts. + //audio->msgAddEvent(event, curPart, false); + audio->msgAddEvent(event, curPart, false, true, true); + + song_changed = true; + } + } + if (song_changed) { + songChanged(0); + return; + } + redraw(); + } + +//--------------------------------------------------------- +// deleteVal +//--------------------------------------------------------- + +void CtrlCanvas::deleteVal(int x1, int x2, int) + { + int xx1 = editor->rasterVal1(x1); + int xx2 = editor->rasterVal2(x2); + + int partTick = curPart->tick(); + xx1 -= partTick; + xx2 -= partTick; + + bool song_changed = false; + for (ciCEvent i = items.begin(); i != items.end(); ++i) { + CEvent* ev = *i; + if(ev->part() != curPart) + continue; + Event event = ev->event(); + if (event.empty()) + continue; + int x = event.tick(); + if (x < xx1) + continue; + if (x >= xx2) + break; + if (!event.empty()) { + // Indicate no undo, and do port controller values and clone parts. + //audio->msgDeleteEvent(event, ev->part(), false); + audio->msgDeleteEvent(event, curPart, false, true, true); + song_changed = true; + } + } + if (song_changed) { + songChanged(0); + return; + } + } + +//--------------------------------------------------------- +// setTool +//--------------------------------------------------------- + +void CtrlCanvas::setTool(int t) + { + if (tool == Tool(t)) + return; + tool = Tool(t); + switch(tool) { + case PencilTool: + setCursor(QCursor(*pencilIcon, 4, 15)); + break; + case DrawTool: + drawLineMode = false; + break; + default: + setCursor(QCursor(Qt::arrowCursor)); + break; + } + } + +//--------------------------------------------------------- +// pdrawItems +//--------------------------------------------------------- + +void CtrlCanvas::pdrawItems(QPainter& p, const QRect& rect, const MidiPart* part, bool velo, bool fg) +{ + int x = rect.x() - 1; // compensate for 3 pixel line width + int w = rect.width() + 2; + int wh = height(); + + if(velo) + { + for(iCEvent i = items.begin(); i != items.end(); ++i) + { + CEvent* e = *i; + // Draw selected part velocity events on top of unselected part events. + //if((fg && e->part() != part) || (!fg && e->part() == part)) + if(e->part() != part) + continue; + int tick = mapx(e->event().tick() + e->part()->tick()); + if (tick <= x) + continue; + if (tick > x+w) + break; + int y1 = wh - (e->val() * wh / 128); + // fg means 'draw selected parts'. + if(fg) + p.setPen(QPen(config.ctrlGraphFg, 3)); + else + p.setPen(QPen(Qt::darkGray, 3)); + p.drawLine(tick, wh, tick, y1); + } + } + else + { + MidiTrack* mt = part->track(); + MidiPort* mp; + + if((mt->type() == Track::DRUM) && (curDrumInstrument != -1) && ((_cnum & 0xff) == 0xff)) + mp = &midiPorts[drumMap[curDrumInstrument].port]; + else + mp = &midiPorts[mt->outPort()]; + + MidiController* mc = mp->midiController(_cnum); + + int min; + int max; + int bias; + if(_cnum == CTRL_PROGRAM) + { + min = 1; + max = 128; + bias = 0; + } + else + { + min = mc->minVal(); + max = mc->maxVal(); + bias = mc->bias(); + } + int x1 = rect.x(); + int lval = CTRL_VAL_UNKNOWN; + noEvents=false; + for (iCEvent i = items.begin(); i != items.end(); ++i) + { + CEvent* e = *i; + // Draw unselected part controller events (lines) on top of selected part events (bars). + //if((fg && (e->part() == part)) || (!fg && (e->part() != part))) + if(e->part() != part) + { + continue; + } + Event ev = e->event(); + int tick = mapx(!ev.empty() ? ev.tick() + e->part()->tick() : 0); + int val = e->val(); + int pval = val; + if(_cnum == CTRL_PROGRAM) + { + if((val & 0xff) == 0xff) + // What to do here? prog = 0xff should not be allowed, but may still be encountered. + pval = 1; + else + pval = (val & 0x7f) + 1; + } + if (tick <= x) { + if (val == CTRL_VAL_UNKNOWN) + lval = CTRL_VAL_UNKNOWN; + else + { + if(_cnum == CTRL_PROGRAM) + lval = wh - ((pval - min - bias) * wh / (max - min)); + else + lval = wh - ((val - min - bias) * wh / (max - min)); + } + continue; + } + if (tick > x+w) + break; + if (lval == CTRL_VAL_UNKNOWN) + { + // fg means 'draw unselected parts'. + if(!fg) + p.fillRect(x1, 0, tick - x1, wh, Qt::darkGray); + } + else + { + if(fg) + { + p.setPen(Qt::gray); + p.drawLine(x1, lval, tick, lval); + } + else + p.fillRect(x1, lval, tick - x1, wh - lval, config.ctrlGraphFg); + } + + + x1 = tick; + if (val == CTRL_VAL_UNKNOWN) + lval = CTRL_VAL_UNKNOWN; + else + { + if(_cnum == CTRL_PROGRAM) + lval = wh - ((pval - min - bias) * wh / (max - min)); + else + lval = wh - ((val - min - bias) * wh / (max - min)); + } + } + if (lval == CTRL_VAL_UNKNOWN) + { + if(!fg) { + p.fillRect(x1, 0, (x+w) - x1, wh, Qt::darkGray); + noEvents=true; + } + } + else + { + if(fg) + { + p.setPen(Qt::gray); + p.drawLine(x1, lval, x + w, lval); + } + else + p.fillRect(x1, lval, (x+w) - x1, wh - lval, config.ctrlGraphFg); + } + } +} + +//--------------------------------------------------------- +// pdraw +//--------------------------------------------------------- + +void CtrlCanvas::pdraw(QPainter& p, const QRect& rect) + { + + int x = rect.x() - 1; // compensate for 3 pixel line width + int y = rect.y(); + int w = rect.width() + 2; + int h = rect.height(); + + + //--------------------------------------------------- + // draw Canvas Items + //--------------------------------------------------- + + bool velo = (midiControllerType(_controller->num()) == MidiController::Velo); + if(!velo) + { + pdrawItems(p, rect, curPart, false, false); + } + for(iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip) + { + MidiPart* part = (MidiPart*)(ip->second); + //if((velo && part == curPart) || (!velo && part != curPart)) + if(part == curPart) + continue; + pdrawItems(p, rect, part, velo, !velo); + } + if(velo) + { + pdrawItems(p, rect, curPart, true, true); + } + + p.save(); + View::pdraw(p, rect); + p.restore(); + + //--------------------------------------------------- + // draw marker + //--------------------------------------------------- + + int xp = mapx(pos[0]); + if (xp >= x && xp < x+w) { + p.setPen(Qt::red); + p.drawLine(xp, y, xp, y+h); + } + xp = mapx(pos[1]); + if (xp >= x && xp < x+w) { + p.setPen(Qt::blue); + p.drawLine(xp, y, xp, y+h); + } + xp = mapx(pos[2]); + if (xp >= x && xp < x+w) { + p.setPen(Qt::blue); + p.drawLine(xp, y, xp, y+h); + } + + //--------------------------------------------------- + // draw lasso + //--------------------------------------------------- + + if (drag == DRAG_LASSO) { + setPainter(p); + p.setPen(Qt::blue); + p.setBrush(Qt::NoBrush); + p.drawRect(lasso); + } + } + +//--------------------------------------------------------- +// drawOverlay +//--------------------------------------------------------- + +void CtrlCanvas::drawOverlay(QPainter& p) + { + QString s(_controller->name()); + p.setFont(config.fonts[3]); + p.setPen(Qt::black); + QFontMetrics fm(config.fonts[3]); + int y = fm.lineSpacing() + 2; + p.drawText(2, y, s); + if (noEvents) { + p.setFont(config.fonts[3]); + p.setPen(Qt::black); + p.drawText(width()/2-100,height()/2-10, "Use shift + pencil or line tool to draw new events"); + //p.drawText(2 , y * 2, "Use shift + pencil or line tool to draw new events"); + } + } + +//--------------------------------------------------------- +// overlayRect +// returns geometry of overlay rectangle +//--------------------------------------------------------- + +QRect CtrlCanvas::overlayRect() const + { + QFontMetrics fm(config.fonts[3]); + QRect r(fm.boundingRect(_controller ? _controller->name() : QString(""))); + r.moveBy(2, 2); // top/left margin + return r; + } + +//--------------------------------------------------------- +// draw +//--------------------------------------------------------- + +void CtrlCanvas::draw(QPainter& p, const QRect& rect) + { + drawTickRaster(p, rect.x(), rect.y(), + //rect.width(), rect.height(), editor->quant()); + rect.width(), rect.height(), editor->raster()); + + //--------------------------------------------------- + // draw line tool + //--------------------------------------------------- + + if (drawLineMode && (tool == DrawTool)) { + p.setPen(Qt::black); + p.drawLine(line1x, line1y, line2x, line2y); + } + } + +//--------------------------------------------------------- +// setCurDrumInstrument +//--------------------------------------------------------- + +void CtrlCanvas::setCurDrumInstrument(int di) + { + curDrumInstrument = di; + //printf("CtrlCanvas::setCurDrumInstrument curDrumInstrument:%d\n", curDrumInstrument); + + // + // check if current controller is only valid for + // a specific drum instrument + // + // Removed by T356. + //if(curTrack && (curTrack->type() == Track::DRUM) && ((_controller->num() & 0xff) == 0xff)) { + //if(curTrack && (curTrack->type() == Track::DRUM) && ((_cnum & 0xff) == 0xff)) { + // reset to default + // TODO: check, if new drum instrument has a similar controller + // configured + // _cnum = CTRL_VELOCITY; + // } + // Removed by T356 + //songChanged(-1); + } diff --git a/muse2/muse/ctrl/ctrlcanvas.h b/muse2/muse/ctrl/ctrlcanvas.h new file mode 100644 index 00000000..bb17fafb --- /dev/null +++ b/muse2/muse/ctrl/ctrlcanvas.h @@ -0,0 +1,165 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: ctrlcanvas.h,v 1.7.2.4 2009/06/01 20:15:53 spamatica Exp $ +// (C) Copyright 1999 Werner Schweer (ws@seh.de) +//========================================================= + +#ifndef __CTRLCANVAS_H__ +#define __CTRLCANVAS_H__ + +#include <list> + + +#include "view.h" +#include "tools.h" +#include "midictrl.h" +#include "event.h" +//Added by qt3to4: +#include <QMouseEvent> +#include <QEvent> + +class Event; +class MidiPart; +class PartList; +class MidiTrack; +class MidiEditor; +class QWidget; +class CtrlPanel; + +//--------------------------------------------------------- +// CEvent +// ''visual'' Controller Event +//--------------------------------------------------------- + +class CEvent { + Event _event; + int _val; + MidiPart* _part; + int ex; + + public: + CEvent(Event e, MidiPart* part, int v); + Event event() const { return _event; } + void setEvent(Event& ev) { _event = ev; } + int val() const { return _val; } + void setVal(int v) { _val = v; } + void setEX(int v) { ex = v; } + MidiPart* part() const { return _part; } + bool contains(int x1, int x2) const; + int x() { return ex; } + }; + +typedef std::list<CEvent*>::iterator iCEvent; +typedef std::list<CEvent*>::const_iterator ciCEvent; + +//--------------------------------------------------------- +// CEventList +// Controller Item List +//--------------------------------------------------------- + +class CEventList: public std::list<CEvent*> { + public: + void add(CEvent* item) { push_back(item); } + + void clearDelete(); + }; + +//--------------------------------------------------------- +// CtrlCanvas +//--------------------------------------------------------- + +class CtrlCanvas : public View { + MidiEditor* editor; + MidiTrack* curTrack; + MidiPart* curPart; + MidiCtrlValList* ctrl; + MidiController* _controller; + CtrlPanel* _panel; + int _cnum; + // Current real drum controller number (anote). + int _dnum; + // Current real drum controller index. + int _didx; + int line1x; + int line1y; + int line2x; + int line2y; + bool drawLineMode; + bool noEvents; + + void viewMousePressEvent(QMouseEvent* event); + void viewMouseMoveEvent(QMouseEvent*); + void viewMouseReleaseEvent(QMouseEvent*); + + virtual void draw(QPainter&, const QRect&); + virtual void pdraw(QPainter&, const QRect&); + virtual void drawOverlay(QPainter& p); + virtual QRect overlayRect() const; + + void changeValRamp(int x1, int x2, int y1, int y2); + void newValRamp(int x1, int y1, int x2, int y2); + void changeVal(int x1, int x2, int y); + void newVal(int x1, int x2, int y); + void deleteVal(int x1, int x2, int y); + + bool setCurTrackAndPart(); + void pdrawItems(QPainter&, const QRect&, const MidiPart*, bool, bool); + void partControllers(const MidiPart*, int, int*, int*, MidiController**, MidiCtrlValList**); + + Q_OBJECT + + protected: + enum DragMode { DRAG_OFF, DRAG_NEW, DRAG_MOVE_START, DRAG_MOVE, + DRAG_DELETE, DRAG_COPY_START, DRAG_COPY, + DRAG_RESIZE, DRAG_LASSO_START, DRAG_LASSO + }; + + CEventList items; + CEventList selection; + CEventList moving; + CEvent* curItem; + + DragMode drag; + QRect lasso; + QPoint start; + Tool tool; + unsigned pos[3]; + int curDrumInstrument; //Used by the drum-editor to view velocity of only one key (one drum) + + void leaveEvent(QEvent*e); + QPoint raster(const QPoint&) const; + + // selection + bool isSingleSelection() { return selection.size() == 1; } + void deselectAll(); + void selectItem(CEvent* e); + void deselectItem(CEvent* e); + + void setMidiController(int); + void updateItems(); + + private slots: + void songChanged(int type); + void setCurDrumInstrument(int); + + public slots: + void setTool(int t); + void setPos(int, unsigned, bool adjustScrollbar); + void setController(int ctrl); + + signals: + void followEvent(int); + void xposChanged(unsigned); + void yposChanged(int); + + public: + CtrlCanvas(MidiEditor*, QWidget* parent, int, + const char* name = 0, CtrlPanel* pnl = 0); + void setPanel(CtrlPanel* pnl) { _panel = pnl; } + MidiCtrlValList* ctrlValList() { return ctrl; } + MidiController* controller() { return _controller; } + MidiTrack* track() const { return curTrack; } + }; +#endif + diff --git a/muse2/muse/ctrl/ctrledit.cpp b/muse2/muse/ctrl/ctrledit.cpp new file mode 100644 index 00000000..bca9d550 --- /dev/null +++ b/muse2/muse/ctrl/ctrledit.cpp @@ -0,0 +1,134 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: ctrledit.cpp,v 1.4.2.2 2009/02/02 21:38:00 terminator356 Exp $ +// (C) Copyright 1999 Werner Schweer (ws@seh.de) +//========================================================= + +#include <stdio.h> +#include "ctrledit.h" +#include "ctrlcanvas.h" +#include "midieditor.h" +#include "xml.h" +#include "vscale.h" +#include "ctrlpanel.h" +#include "globals.h" +#include "midiport.h" +#include "instruments/minstrument.h" +#include "gconfig.h" + +#include <qlayout.h> +#include <qpainter.h> +#include <qtoolbutton.h> +#include <q3popupmenu.h> +#include <qlabel.h> +//Added by qt3to4: +#include <Q3HBoxLayout> + +//--------------------------------------------------------- +// setTool +//--------------------------------------------------------- + +void CtrlEdit::setTool(int t) + { + canvas->setTool(t); + } + +//--------------------------------------------------------- +// CtrlEdit +//--------------------------------------------------------- + +CtrlEdit::CtrlEdit(QWidget* parent, MidiEditor* e, int xmag, + bool expand, const char* name) : QWidget(parent, name) + { + Q3HBoxLayout* hbox = new Q3HBoxLayout(this); + panel = new CtrlPanel(this, e, "panel"); + canvas = new CtrlCanvas(e, this, xmag, "ctrlcanvas", panel); + QWidget* vscale = new VScale(this); + + canvas->setOrigin(-(config.division/4), 0); + + canvas->setMinimumHeight(50); + + panel->setFixedWidth(CTRL_PANEL_FIXED_WIDTH); + hbox->addWidget(panel, expand ? 100 : 0, Qt::AlignRight); + hbox->addWidget(canvas, 100); + hbox->addWidget(vscale, 0); + + connect(panel, SIGNAL(destroyPanel()), SLOT(destroy())); + connect(panel, SIGNAL(controllerChanged(int)), canvas, SLOT(setController(int))); + connect(canvas, SIGNAL(xposChanged(unsigned)), SIGNAL(timeChanged(unsigned))); + connect(canvas, SIGNAL(yposChanged(int)), SIGNAL(yposChanged(int))); + } + +//--------------------------------------------------------- +// writeStatus +//--------------------------------------------------------- + +void CtrlEdit::writeStatus(int level, Xml& xml) + { + if (canvas->controller()) { + xml.tag(level++, "ctrledit"); + xml.strTag(level, "ctrl", canvas->controller()->name()); + xml.tag(level, "/ctrledit"); + } + } + +//--------------------------------------------------------- +// readStatus +//--------------------------------------------------------- + +void CtrlEdit::readStatus(Xml& xml) + { + for (;;) { + Xml::Token token = xml.parse(); + const QString& tag = xml.s1(); + switch (token) { + case Xml::Error: + case Xml::End: + return; + case Xml::TagStart: + if (tag == "ctrl") { + QString name = xml.parse1(); + int portno = canvas->track()->outPort(); + MidiPort* port = &midiPorts[portno]; + MidiInstrument* instr = port->instrument(); + MidiControllerList* mcl = instr->controller(); + + for (iMidiController ci = mcl->begin(); ci != mcl->end(); ++ci) { + if (ci->second->name() == name) { + canvas->setController(ci->second->num()); + break; + } + } + } + else + xml.unknown("CtrlEdit"); + break; + case Xml::TagEnd: + if (tag == "ctrledit") + return; + default: + break; + } + } + } + +//--------------------------------------------------------- +// destroy +//--------------------------------------------------------- + +void CtrlEdit::destroy() + { + emit destroyedCtrl(this); + close(true); // close and destroy widget + } + +//--------------------------------------------------------- +// setCanvasWidth +//--------------------------------------------------------- + +void CtrlEdit::setCanvasWidth(int w) +{ + canvas->setFixedWidth(w); +} diff --git a/muse2/muse/ctrl/ctrledit.h b/muse2/muse/ctrl/ctrledit.h new file mode 100644 index 00000000..2af7c528 --- /dev/null +++ b/muse2/muse/ctrl/ctrledit.h @@ -0,0 +1,56 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: ctrledit.h,v 1.4.2.1 2008/05/21 00:28:53 terminator356 Exp $ +// (C) Copyright 1999 Werner Schweer (ws@seh.de) +//========================================================= + +#ifndef __CTRL_EDIT_H__ +#define __CTRL_EDIT_H__ + +#include <qwidget.h> +//Added by qt3to4: +#include <QLabel> +#include "ctrlcanvas.h" +#include "song.h" + +class MidiEditor; +class QLabel; +class QToolButton; +class CtrlView; +class CtrlPanel; +class Xml; + +#define CTRL_PANEL_FIXED_WIDTH 40 +//--------------------------------------------------------- +// CtrlEdit +//--------------------------------------------------------- + +class CtrlEdit : public QWidget { + CtrlCanvas* canvas; + CtrlPanel* panel; + Q_OBJECT + + private slots: + void destroy(); + + public slots: + void setTool(int tool); + void setXPos(int val) { canvas->setXPos(val); } + void setXMag(int val) { canvas->setXMag(val); } + void setCanvasWidth(int w); + signals: + void timeChanged(unsigned); + void destroyedCtrl(CtrlEdit*); + void enterCanvas(); + void yposChanged(int); + + public: + CtrlEdit(QWidget*, MidiEditor* e, int xmag, + bool expand = false, const char* name = 0); + void readStatus(Xml&); + void writeStatus(int, Xml&); + }; + +#endif + diff --git a/muse2/muse/ctrl/ctrlpanel.cpp b/muse2/muse/ctrl/ctrlpanel.cpp new file mode 100644 index 00000000..820e6428 --- /dev/null +++ b/muse2/muse/ctrl/ctrlpanel.cpp @@ -0,0 +1,694 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: ctrlpanel.cpp,v 1.10.2.9 2009/06/14 05:24:45 terminator356 Exp $ +// (C) Copyright 1999-2004 Werner Schweer (ws@seh.de) +//========================================================= + +#include <stdio.h> +#include <list> + +#include "ctrlpanel.h" +#include "ctrlcanvas.h" + +#include <qlayout.h> +#include <qpushbutton.h> +#include <q3popupmenu.h> +#include <qlabel.h> +#include <qtooltip.h> +#include <qsizepolicy.h> +#include <qtimer.h> +//Added by qt3to4: +#include <Q3HBoxLayout> +#include <Q3VBoxLayout> +#include <math.h> + +#include "globals.h" +#include "midictrl.h" +#include "instruments/minstrument.h" +#include "midiport.h" +#include "xml.h" +#include "icons.h" +#include "event.h" +#include "midieditor.h" +#include "track.h" +#include "part.h" +#include "midiedit/drummap.h" +#include "gconfig.h" +#include "song.h" +#include "knob.h" +#include "doublelabel.h" +#include "midi.h" +#include "audio.h" + +//--------------------------------------------------------- +// CtrlPanel +//--------------------------------------------------------- + +CtrlPanel::CtrlPanel(QWidget* parent, MidiEditor* e, const char* name) + : QWidget(parent, name) + { + inHeartBeat = true; + editor = e; + setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); + Q3VBoxLayout* vbox = new Q3VBoxLayout(this); + Q3HBoxLayout* bbox = new Q3HBoxLayout(vbox); + vbox->addStretch(); + Q3HBoxLayout* kbox = new Q3HBoxLayout(vbox); + Q3HBoxLayout* dbox = new Q3HBoxLayout(vbox); + vbox->addStretch(); + selCtrl = new QPushButton(tr("S"), this, "selCtrl"); + selCtrl->setFont(config.fonts[3]); + selCtrl->setFixedHeight(20); + selCtrl->setSizePolicy( + QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); + QToolTip::add(selCtrl, tr("select controller")); + pop = new Q3PopupMenu(selCtrl); + + // destroy button + QPushButton* destroy = new QPushButton(tr("X"), this, "destroy"); + destroy->setFont(config.fonts[3]); + destroy->setFixedHeight(20); + destroy->setSizePolicy( + QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); + QToolTip::add(destroy, tr("remove panel")); + // Cursor Position + connect(selCtrl, SIGNAL(clicked()), SLOT(ctrlPopup())); + connect(destroy, SIGNAL(clicked()), SIGNAL(destroyPanel())); + + _track = 0; + _ctrl = 0; + _val = CTRL_VAL_UNKNOWN; + _dnum = -1; + + _knob = new Knob(this); + _knob->setFixedWidth(25); + _knob->setFixedHeight(25); + QToolTip::add(_knob, tr("manual adjust")); + _knob->setRange(0.0, 127.0, 1.0); + _knob->setValue(0.0); + _knob->setEnabled(false); + _knob->hide(); + _knob->setAltFaceColor(Qt::red); + + _dl = new DoubleLabel(-1.0, 0.0, +127.0, this); + _dl->setPrecision(0); + QToolTip::add(_dl, tr("double click on/off")); + _dl->setSpecialText(tr("off")); + _dl->setFont(config.fonts[1]); + _dl->setBackgroundMode(Qt::PaletteMid); + _dl->setFrame(true); + _dl->setFixedWidth(36); + _dl->setFixedHeight(15); + _dl->setEnabled(false); + _dl->hide(); + + connect(_knob, SIGNAL(sliderMoved(double,int)), SLOT(ctrlChanged(double))); + connect(_knob, SIGNAL(sliderRightClicked(const QPoint&, int)), SLOT(ctrlRightClicked(const QPoint&, int))); + //connect(_knob, SIGNAL(sliderReleased(int)), SLOT(ctrlReleased(int))); + connect(_dl, SIGNAL(valueChanged(double,int)), SLOT(ctrlChanged(double))); + connect(_dl, SIGNAL(doubleClicked(int)), SLOT(labelDoubleClicked())); + + bbox->addStretch(); + bbox->addWidget(selCtrl); + bbox->addWidget(destroy); + bbox->addStretch(); + kbox->addStretch(); + kbox->addWidget(_knob); + kbox->addStretch(); + dbox->addStretch(); + dbox->addWidget(_dl); + dbox->addStretch(); + connect(heartBeatTimer, SIGNAL(timeout()), SLOT(heartBeat())); + inHeartBeat = false; + } +//--------------------------------------------------------- +// heartBeat +//--------------------------------------------------------- + +void CtrlPanel::heartBeat() +{ + inHeartBeat = true; + + if(_track && _ctrl && _dnum != -1) + { + //if(_dnum != CTRL_VELOCITY && _dnum != CTRL_PROGRAM) + if(_dnum != CTRL_VELOCITY) + { + int outport; + int chan; + int cdi = editor->curDrumInstrument(); + if(_track->type() == Track::DRUM && ((_ctrl->num() & 0xff) == 0xff) && cdi != -1) + { + outport = drumMap[cdi].port; + chan = drumMap[cdi].channel; + } + else + { + outport = _track->outPort(); + chan = _track->outChannel(); + } + MidiPort* mp = &midiPorts[outport]; + + int v = mp->hwCtrlState(chan, _dnum); + if(v == CTRL_VAL_UNKNOWN) + { + // DoubleLabel ignores the value if already set... + _dl->setValue(_dl->off() - 1.0); + _val = CTRL_VAL_UNKNOWN; + v = mp->lastValidHWCtrlState(chan, _dnum); + if(v != CTRL_VAL_UNKNOWN && ((_dnum != CTRL_PROGRAM) || ((v & 0xff) != 0xff) )) + { + if(_dnum == CTRL_PROGRAM) + v = (v & 0x7f) + 1; + else + // Auto bias... + v -= _ctrl->bias(); + if(double(v) != _knob->value()) + { + // Added by Tim. p3.3.6 + //printf("CtrlPanel::heartBeat setting knob\n"); + + _knob->setValue(double(v)); + } + } + } + else + if(v != _val) + { + _val = v; + if(v == CTRL_VAL_UNKNOWN || ((_dnum == CTRL_PROGRAM) && ((v & 0xff) == 0xff) )) + { + // DoubleLabel ignores the value if already set... + //_dl->setValue(double(_ctrl->minVal() - 1)); + _dl->setValue(_dl->off() - 1.0); + } + else + { + if(_dnum == CTRL_PROGRAM) + v = (v & 0x7f) + 1; + else + // Auto bias... + v -= _ctrl->bias(); + + // Added by Tim. p3.3.6 + //printf("CtrlPanel::heartBeat setting knob and label\n"); + + _knob->setValue(double(v)); + _dl->setValue(double(v)); + } + } + } + } + + inHeartBeat = false; +} + +//--------------------------------------------------------- +// labelDoubleClicked +//--------------------------------------------------------- + +void CtrlPanel::labelDoubleClicked() +{ + if(!_track || !_ctrl || _dnum == -1) + return; + + int outport; + int chan; + int cdi = editor->curDrumInstrument(); + if(_track->type() == Track::DRUM && ((_ctrl->num() & 0xff) == 0xff) && cdi != -1) + { + outport = drumMap[cdi].port; + chan = drumMap[cdi].channel; + } + else + { + outport = _track->outPort(); + chan = _track->outChannel(); + } + MidiPort* mp = &midiPorts[outport]; + int lastv = mp->lastValidHWCtrlState(chan, _dnum); + + int curv = mp->hwCtrlState(chan, _dnum); + + if(_dnum == CTRL_PROGRAM) + { + if(curv == CTRL_VAL_UNKNOWN || ((curv & 0xffffff) == 0xffffff)) + { + // If no value has ever been set yet, use the current knob value + // (or the controller's initial value?) to 'turn on' the controller. + if(lastv == CTRL_VAL_UNKNOWN || ((lastv & 0xffffff) == 0xffffff)) + { + //int kiv = _ctrl->initVal()); + int kiv = lrint(_knob->value()); + --kiv; + kiv &= 0x7f; + kiv |= 0xffff00; + //MidiPlayEvent ev(song->cpos(), outport, chan, ME_CONTROLLER, _dnum, kiv); + MidiPlayEvent ev(0, outport, chan, ME_CONTROLLER, _dnum, kiv); + audio->msgPlayMidiEvent(&ev); + } + else + { + //MidiPlayEvent ev(song->cpos(), outport, chan, ME_CONTROLLER, _dnum, lastv); + MidiPlayEvent ev(0, outport, chan, ME_CONTROLLER, _dnum, lastv); + audio->msgPlayMidiEvent(&ev); + } + } + else + { + //if((curv & 0xffff00) == 0xffff00) + //{ + ////if(mp->hwCtrlState(chan, _dnum) != CTRL_VAL_UNKNOWN) + audio->msgSetHwCtrlState(mp, chan, _dnum, CTRL_VAL_UNKNOWN); + //} + //else + //{ + // MidiPlayEvent ev(song->cpos(), outport, chan, ME_CONTROLLER, _dnum, (curv & 0xffff00) | 0xff); + // audio->msgPlayMidiEvent(&ev); + //} + } + } + else + { + if(curv == CTRL_VAL_UNKNOWN) + { + // If no value has ever been set yet, use the current knob value + // (or the controller's initial value?) to 'turn on' the controller. + if(lastv == CTRL_VAL_UNKNOWN) + { + //int kiv = _ctrl->initVal()); + int kiv = lrint(_knob->value()); + if(kiv < _ctrl->minVal()) + kiv = _ctrl->minVal(); + if(kiv > _ctrl->maxVal()) + kiv = _ctrl->maxVal(); + kiv += _ctrl->bias(); + //MidiPlayEvent ev(song->cpos(), outport, chan, ME_CONTROLLER, _dnum, kiv); + MidiPlayEvent ev(0, outport, chan, ME_CONTROLLER, _dnum, kiv); + audio->msgPlayMidiEvent(&ev); + } + else + { + //MidiPlayEvent ev(song->cpos(), outport, chan, ME_CONTROLLER, _dnum, lastv); + MidiPlayEvent ev(0, outport, chan, ME_CONTROLLER, _dnum, lastv); + audio->msgPlayMidiEvent(&ev); + } + } + else + { + //if(mp->hwCtrlState(chan, _dnum) != CTRL_VAL_UNKNOWN) + audio->msgSetHwCtrlState(mp, chan, _dnum, CTRL_VAL_UNKNOWN); + } + } + song->update(SC_MIDI_CONTROLLER); +} + +//--------------------------------------------------------- +// ctrlChanged +//--------------------------------------------------------- + +void CtrlPanel::ctrlChanged(double val) + { + if (inHeartBeat) + return; + if(!_track || !_ctrl || _dnum == -1) + return; + + int ival = lrint(val); + + int outport; + int chan; + int cdi = editor->curDrumInstrument(); + if(_track->type() == Track::DRUM && ((_ctrl->num() & 0xff) == 0xff) && cdi != -1) + { + outport = drumMap[cdi].port; + chan = drumMap[cdi].channel; + } + else + { + outport = _track->outPort(); + chan = _track->outChannel(); + } + MidiPort* mp = &midiPorts[outport]; + int curval = mp->hwCtrlState(chan, _dnum); + + if(_dnum == CTRL_PROGRAM) + { + --ival; + ival &= 0x7f; + + if(curval == CTRL_VAL_UNKNOWN) + ival |= 0xffff00; + else + ival |= (curval & 0xffff00); + //MidiPlayEvent ev(song->cpos(), outport, chan, ME_CONTROLLER, _dnum, ival); + MidiPlayEvent ev(0, outport, chan, ME_CONTROLLER, _dnum, ival); + audio->msgPlayMidiEvent(&ev); + } + else + // Shouldn't happen, but... + if((ival < _ctrl->minVal()) || (ival > _ctrl->maxVal())) + { + //if(mp->hwCtrlState(chan, _dnum) != CTRL_VAL_UNKNOWN) + if(curval != CTRL_VAL_UNKNOWN) + audio->msgSetHwCtrlState(mp, chan, _dnum, CTRL_VAL_UNKNOWN); + } + else + { + // Auto bias... + ival += _ctrl->bias(); + + //MidiPlayEvent ev(song->cpos(), outport, chan, ME_CONTROLLER, _dnum, ival); + MidiPlayEvent ev(0, outport, chan, ME_CONTROLLER, _dnum, ival); + audio->msgPlayMidiEvent(&ev); + } + song->update(SC_MIDI_CONTROLLER); + } + +//--------------------------------------------------------- +// setHWController +//--------------------------------------------------------- + +void CtrlPanel::setHWController(MidiTrack* t, MidiController* ctrl) +{ + inHeartBeat = true; + + _track = t; _ctrl = ctrl; + + if(!_track || !_ctrl) + { + _knob->setEnabled(false); + _dl->setEnabled(false); + _knob->hide(); + _dl->hide(); + inHeartBeat = false; + return; + } + + MidiPort* mp; + int ch; + int cdi = editor->curDrumInstrument(); + _dnum = _ctrl->num(); + if(_track->type() == Track::DRUM && ((_dnum & 0xff) == 0xff) && cdi != -1) + { + _dnum = (_dnum & ~0xff) | drumMap[cdi].anote; + mp = &midiPorts[drumMap[cdi].port]; + ch = drumMap[cdi].channel; + } + else + { + mp = &midiPorts[_track->outPort()]; + ch = _track->outChannel(); + } + + //if(_dnum == CTRL_VELOCITY || _dnum == CTRL_PROGRAM) + if(_dnum == CTRL_VELOCITY) + { + _knob->setEnabled(false); + _dl->setEnabled(false); + _knob->hide(); + _dl->hide(); + } + else + { + _knob->setEnabled(true); + _dl->setEnabled(true); + double dlv; + int mn; int mx; int v; + if(_dnum == CTRL_PROGRAM) + { + mn = 1; + mx = 128; + v = mp->hwCtrlState(ch, _dnum); + _val = v; + _knob->setRange(double(mn), double(mx), 1.0); + _dl->setRange(double(mn), double(mx)); + //_dl->setOff(double(mn - 1)); + if(v == CTRL_VAL_UNKNOWN || ((v & 0xffffff) == 0xffffff)) + { + int lastv = mp->lastValidHWCtrlState(ch, _dnum); + if(lastv == CTRL_VAL_UNKNOWN || ((lastv & 0xffffff) == 0xffffff)) + { + int initv = _ctrl->initVal(); + if(initv == CTRL_VAL_UNKNOWN || ((initv & 0xffffff) == 0xffffff)) + v = 1; + else + v = (initv + 1) & 0xff; + } + else + v = (lastv + 1) & 0xff; + + if(v > 128) + v = 128; + //dlv = mn - 1; + dlv = _dl->off() - 1.0; + } + else + { + v = (v + 1) & 0xff; + if(v > 128) + v = 128; + dlv = double(v); + } + } + else + { + mn = _ctrl->minVal(); + mx = _ctrl->maxVal(); + v = mp->hwCtrlState(ch, _dnum); + _val = v; + _knob->setRange(double(mn), double(mx), 1.0); + _dl->setRange(double(mn), double(mx)); + //_dl->setOff(double(mn - 1)); + if(v == CTRL_VAL_UNKNOWN) + { + int lastv = mp->lastValidHWCtrlState(ch, _dnum); + if(lastv == CTRL_VAL_UNKNOWN) + { + if(_ctrl->initVal() == CTRL_VAL_UNKNOWN) + v = 0; + else + v = _ctrl->initVal(); + } + else + v = lastv - _ctrl->bias(); + //dlv = mn - 1; + dlv = _dl->off() - 1.0; + } + else + { + // Auto bias... + v -= _ctrl->bias(); + dlv = double(v); + } + } + _knob->setValue(double(v)); + _dl->setValue(dlv); + + _knob->show(); + _dl->show(); + // Incomplete drawing sometimes. Update fixes it. + _knob->update(); + _dl->update(); + } + + inHeartBeat = false; +} + +//--------------------------------------------------------- +// setHeight +//--------------------------------------------------------- + +void CtrlPanel::setHeight(int h) + { + setFixedHeight(h); + } + +struct CI { + QString s; + bool used; + CI(const QString& ss, bool u) : s(ss), used(u) {} + }; + +//--------------------------------------------------------- +// ctrlPopup +//--------------------------------------------------------- + +void CtrlPanel::ctrlPopup() + { + //--------------------------------------------------- + // build list of midi controllers for current + // MidiPort/channel + //--------------------------------------------------- + + PartList* parts = editor->parts(); + Part* part = editor->curCanvasPart(); + MidiTrack* track = (MidiTrack*)(part->track()); + int channel = track->outChannel(); + MidiPort* port = &midiPorts[track->outPort()]; + int curDrumInstrument = editor->curDrumInstrument(); + bool isDrum = track->type() == Track::DRUM; + + pop->clear(); + pop->insertItem(tr("Velocity"), 1); + + MidiCtrlValListList* cll = port->controller(); + int min = channel << 24; + int max = min + 0x1000000; + + std::list<CI> sList; + typedef std::list<CI>::iterator isList; + + for (iMidiCtrlValList i = cll->lower_bound(min); i != cll->lower_bound(max); ++i) { + MidiCtrlValList* cl = i->second; + MidiController* c = port->midiController(cl->num()); + // dont show drum specific controller if not a drum track + if ((c->num() & 0xff) == 0xff) { + if (!isDrum) + continue; + // only show controller for curDrumInstrument: + if ((cl->num() & 0xff) != drumMap[curDrumInstrument].anote) { + continue; + } + } + isList i = sList.begin(); + for (; i != sList.end(); ++i) { + if (i->s == c->name()) + break; + } + if (i == sList.end()) { + bool used = false; + for (iPart ip = parts->begin(); ip != parts->end(); ++ip) { + EventList* el = ip->second->events(); + for (iEvent ie = el->begin(); ie != el->end(); ++ie) { + Event e = ie->second; + if ((e.type() == Controller) && (e.dataA() == cl->num())) { + used = true; + break; + } + } + if (used) + break; + } + sList.push_back(CI(c->name(), used)); + } + } + for (isList i = sList.begin(); i != sList.end(); ++i) { + if (i->used) + pop->insertItem(QIcon(*greendotIcon), i->s); + else + pop->insertItem(i->s); + } + + pop->insertItem(QIcon(*configureIcon), tr("add new ..."), 2); + int rv = pop->exec(selCtrl->mapToGlobal(QPoint(0,0))); + selCtrl->setDown(false); + + if (rv == -1) + return; + + QString s = pop->text(rv); + if (rv == 1) { // special case velocity + emit controllerChanged(CTRL_VELOCITY); + } + else if (rv == 2) { + // + // add new controller + // + Q3PopupMenu* pop1 = new Q3PopupMenu(this); + pop1->setCheckable(false); + // + // populate popup with all controllers available for + // current instrument + // + MidiInstrument* instr = port->instrument(); + MidiControllerList* mcl = instr->controller(); + for (iMidiController ci = mcl->begin(); ci != mcl->end(); ++ci) + { + int num = ci->second->num(); + if (isDrum && ((num & 0xff) == 0xff)) + num = (num & ~0xff) + drumMap[curDrumInstrument].anote; + + if(cll->find(channel, num) == cll->end()) + pop1->insertItem(ci->second->name()); + } + int rv = pop1->exec(selCtrl->mapToGlobal(QPoint(0,0))); + if (rv != -1) { + QString s = pop1->text(rv); + MidiController* c; + for (iMidiController ci = mcl->begin(); ci != mcl->end(); ++ci) { + c = ci->second; + if (c->name() == s) { + int num = c->num(); + if (isDrum && ((num & 0xff) == 0xff)) + num = (num & ~0xff) + drumMap[curDrumInstrument].anote; + + if(cll->find(channel, num) == cll->end()) + { + MidiCtrlValList* vl = new MidiCtrlValList(num); + + cll->add(channel, vl); + emit controllerChanged(c->num()); + //song->update(SC_MIDI_CONTROLLER_ADD); + } + else + emit controllerChanged(c->num()); + break; + } + } + } + } + else if (rv == -1) + return; + else { + QString s = pop->text(rv); + iMidiCtrlValList i = cll->begin(); + for (; i != cll->end(); ++i) { + MidiCtrlValList* cl = i->second; + MidiController* c = port->midiController(cl->num()); + if (c->name() == s) { + emit controllerChanged(c->num()); + break; + } + } + if (i == cll->end()) { + printf("CtrlPanel: controller %s not found!", s.latin1()); + } + } + } + +//--------------------------------------------------------- +// ctrlRightClicked +//--------------------------------------------------------- + +void CtrlPanel::ctrlRightClicked(const QPoint& p, int /*id*/) +{ + //if(!_knob->selectedFaceColor()) + // _knob->selectFaceColor(true); + //if(_dnum == -1) + // return; + if(!editor->curCanvasPart()) + return; + + int cdi = editor->curDrumInstrument(); + int ctlnum = _ctrl->num(); + if(_track->type() == Track::DRUM && ((ctlnum & 0xff) == 0xff) && cdi != -1) + //ctlnum = (ctlnum & ~0xff) | drumMap[cdi].enote; + ctlnum = (ctlnum & ~0xff) | cdi; + + MidiPart* part = dynamic_cast<MidiPart*>(editor->curCanvasPart()); + song->execMidiAutomationCtlPopup(0, part, p, ctlnum); +} + +/* +//--------------------------------------------------------- +// ctrlReleased +//--------------------------------------------------------- + +void CtrlPanel::ctrlReleased(int id) +{ + //if(_knob->selectedFaceColor()) + // _knob->selectFaceColor(false); +} +*/ diff --git a/muse2/muse/ctrl/ctrlpanel.h b/muse2/muse/ctrl/ctrlpanel.h new file mode 100644 index 00000000..8d3379c0 --- /dev/null +++ b/muse2/muse/ctrl/ctrlpanel.h @@ -0,0 +1,66 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: ctrlpanel.h,v 1.2.2.5 2009/06/10 00:34:59 terminator356 Exp $ +// (C) Copyright 1999-2001 Werner Schweer (ws@seh.de) +//========================================================= + +#ifndef __CTRL_PANEL_H__ +#define __CTRL_PANEL_H__ + +#include <qwidget.h> +//Added by qt3to4: +#include <Q3PopupMenu> +#include <QLabel> + +class MidiController; +class QLabel; +class Q3PopupMenu; +class QPushButton; +class MidiEditor; +class Knob; +class DoubleLabel; +class MidiPort; +class MidiTrack; + +//--------------------------------------------------------- +// CtrlPanel +//--------------------------------------------------------- + +class CtrlPanel: public QWidget { + Q3PopupMenu* pop; + QPushButton* selCtrl; + MidiEditor* editor; + + MidiTrack* _track; + MidiController* _ctrl; + int _dnum; + bool inHeartBeat; + Knob* _knob; + DoubleLabel* _dl; + int _val; + + Q_OBJECT + + signals: + void destroyPanel(); + void controllerChanged(int); + + private slots: + void ctrlChanged(double val); + void labelDoubleClicked(); + void ctrlRightClicked(const QPoint& p, int id); + //void ctrlReleased(int id); + + protected slots: + virtual void heartBeat(); + + public slots: + void setHeight(int); + void ctrlPopup(); + + public: + CtrlPanel(QWidget*, MidiEditor*, const char* name = 0); + void setHWController(MidiTrack* t, MidiController* ctrl); + }; +#endif |