1# -*- coding: utf-8 -*-
2"""
3Widget collecting subwidgets for the target filter specifications (currently
4only amplitude and frequency specs.)
5
6Author: Christian Muenker
7"""
8from __future__ import print_function, division, unicode_literals, absolute_import
9import sys
10import logging
11logger = logging.getLogger(__name__)
12
13from ..compat import (QWidget, QLabel, QFont, QFrame, pyqtSignal, Qt,
14                      QHBoxLayout, QVBoxLayout)
15
16import pyfda.filterbroker as fb
17from pyfda.input_widgets import amplitude_specs, freq_specs
18from pyfda.pyfda_rc import params
19
20
21class TargetSpecs(QWidget):
22    """
23    Build and update widget for entering the target specifications (frequencies
24    and amplitudes) like F_SB, F_PB, A_SB, etc.
25    """
26
27    # class variables (shared between instances if more than one exists)
28    sigSpecsChanged = pyqtSignal() # emitted when filter has been changed
29
30
31    def __init__(self, parent, title = "Target Specs"):
32        super(TargetSpecs, self).__init__(parent)
33
34        self.title = title
35
36        self._construct_UI()
37
38#------------------------------------------------------------------------------
39    def _construct_UI(self):
40        """
41        Construct user interface
42        """
43
44        # subwidget for Frequency Specs
45        self.f_specs = freq_specs.FreqSpecs(self, title = "Frequency")
46        # subwidget for Amplitude Specs
47        self.a_specs = amplitude_specs.AmplitudeSpecs(self, title = "Amplitude")
48
49        self.a_specs.setVisible(True)
50        """
51        LAYOUT
52        """
53        bfont = QFont()
54        bfont.setBold(True)
55        lblTitle = QLabel(self) # field for widget title
56        lblTitle.setText(self.title)
57        lblTitle.setFont(bfont)
58#        lblTitle.setContentsMargins(2,2,2,2)
59
60        layHTitle = QHBoxLayout()
61        layHTitle.addWidget(lblTitle)
62        layHTitle.setAlignment(Qt.AlignHCenter)
63        layHSpecs = QHBoxLayout()
64        layHSpecs.setAlignment(Qt.AlignTop)
65        layHSpecs.addWidget(self.f_specs) # frequency specs
66        layHSpecs.addWidget(self.a_specs) # ampltitude specs
67
68        layVSpecs = QVBoxLayout()
69        layVSpecs.addLayout(layHTitle)
70        layVSpecs.addLayout(layHSpecs)
71        layVSpecs.setContentsMargins(0,6,0,0) # (left, top, right, bottom)
72
73        # This is the top level widget, encompassing the other widgets
74        frmMain = QFrame(self)
75        frmMain.setLayout(layVSpecs)
76
77        self.layVMain = QVBoxLayout() # Widget main layout
78        self.layVMain.addWidget(frmMain)
79        self.layVMain.setContentsMargins(*params['wdg_margins'])
80
81        self.setLayout(self.layVMain)
82
83        #----------------------------------------------------------------------
84        #  SIGNALS & SLOTS
85        self.a_specs.sigSpecsChanged.connect(self.sigSpecsChanged.emit)
86        self.f_specs.sigSpecsChanged.connect(self.sigSpecsChanged.emit)
87
88        self.update_UI() # first time initialization
89
90
91#------------------------------------------------------------------------------
92    def update_UI(self, new_labels = ()):
93        """
94        Called when a new filter design algorithm has been selected
95        Pass frequency and amplitude labels to the amplitude and frequency
96        spec widgets
97        The sigSpecsChanged signal is emitted already by select_filter.py
98        """
99
100        # pass new labels to widgets. The first element of the 'amp' and the
101        # 'freq' tuple is the state, 'u' is for 'unused', 'd' is for disabled
102
103        if ('frq' in new_labels and len(new_labels['frq']) > 1 and
104                                              new_labels['frq'][0] != 'i'):
105            self.f_specs.show()
106            self.f_specs.setEnabled(new_labels['frq'][0] != 'd')
107            self.f_specs.update_UI(new_labels=new_labels['frq'])
108        else:
109            self.f_specs.hide()
110
111        if ('amp' in new_labels and len(new_labels['amp']) > 1 and
112                                              new_labels['amp'][0] != 'i'):
113            self.a_specs.show()
114            self.a_specs.setEnabled(new_labels['amp'][0] != 'd')
115            self.a_specs.update_UI(new_labels=new_labels['amp'])
116        else:
117            self.a_specs.hide()
118#
119        self.sigSpecsChanged.emit() # ->pyFDA -> pltWidgets.updateAll()
120
121#------------------------------------------------------------------------------
122    def load_dict(self):
123        """
124        Update entries from global dict fb.fil[0]
125        parameters, using the "load_dict" methods of the classes
126        """
127        self.a_specs.load_dict() # magnitude specs with unit
128        self.f_specs.load_dict() # weight specification
129
130#------------------------------------------------------------------------------
131
132if __name__ == '__main__':
133
134    from ..compat import QApplication
135    app = QApplication(sys.argv)
136
137    # Read freq / amp / weight labels for current filter design
138    rt = fb.fil[0]['rt']
139    ft = fb.fil[0]['ft']
140    fc = fb.fil[0]['fc']
141
142    if 'min' in fb.fil_tree[rt][ft][fc]:
143        my_params = fb.fil_tree[rt][ft][fc]['min']['par']
144    else:
145        my_params = {}
146
147    # build separate parameter lists according to the first letter
148    freq_params = [l for l in my_params if l[0] == 'F']
149    amp_params = [l for l in my_params if l[0] == 'A']
150
151    mainw = TargetSpecs(None, title = "Test Specs")
152    mainw.update_UI(freq_params, amp_params)
153
154    app.setActiveWindow(mainw)
155    mainw.show()
156    sys.exit(app.exec_())