Ticket #2412 (closed feature: obsolete)

Opened 15 years ago

Last modified 13 years ago

integrate-scroller -- Integrate scroller component in opened books tabbar and book panel

Reported by: deyan Owned by: stefan
Priority: major Milestone: X3
Component: uncategorized Version: 2.0
Keywords: Cc:
Category: unknown Effort:
Importance: Ticket_group:
Estimated Number of Hours: 0 Add Hours to Ticket: 0
Billable?: yes Total Hours: 0
Analysis_owners: deyan Design_owners: stefan
Imp._owners: stefan Test_owners:
Analysis_reviewers: stefan Changelog: Changelog
Design_reviewers: pap, meddle, deyan Imp._reviewers: deyan, pap
Test_reviewers: Analysis_score: 3
Design_score: 3 Imp._score: 3
Test_score: 0

Description

  • Integrate scroller component in opened books tabbar
    • Scroller arrows should appear when there is no more space for tab buttons
    • Scroller arrows should be skinnable (images)
  • Integrate scroller component in book panel
    • Scroller arrows should appear when there is no more space for panel controls (horizontally)
    • Scrollbars for the panel should never appear
    • Scroller arrows should be skinnable (images)
  • Provide icons for the components
  • Optional - mouse wheel should scroll the scroller when mouse over

Attachments

2412_de_fi.patch (23.1 KB) - added by stefan 15 years ago.
customScrollPane.zip (18.0 KB) - added by stefan 15 years ago.
2412_de_fi_eclipse.patch (22.6 KB) - added by stefan 15 years ago.
2412_im_fi.2.patch (31.8 KB) - added by stefan 15 years ago.
2412_im_fi.patch (31.8 KB) - added by stefan 15 years ago.

Change History

comment:1 Changed 15 years ago by deyan

  • Owner set to deyan
  • Status changed from new to s1a_analysis_started

comment:2 Changed 15 years ago by deyan

  • Status changed from s1a_analysis_started to s1b_analysis_finished

comment:3 Changed 15 years ago by stefan

  • Design_owners set to stefan
  • Status changed from s1b_analysis_finished to s1c_analysis_ok
  • Analysis_reviewers set to stefan
  • Analysis_score changed from 0 to 3

Analysis seems to be o.k., except the part with the icons - I don't believe it should be part of the ticket - i.e. either the icons should be provided in the analysis (by the experience team) or icons shouldn't be in the ticket at all. Nevertheless I'll consult with dido, to give me the needed icons.

3p.

comment:4 Changed 15 years ago by stefan

  • Owner changed from deyan to stefan
  • Status changed from s1c_analysis_ok to s2a_design_started

comment:5 Changed 15 years ago by stefan

  • Status changed from s2a_design_started to s2b_design_finished

List of classes needed to be changed in order to integrate the scroller:

  • ScrollPaneLayout - a tailing component (Jpanel) is added in order to fix various problems (styling and alignment) regarding the AppTabBar, where there is tailing component with specific styling. If there is no need of tailing component, it can be set to null, and it won't have any influence on ScrollPaneLayout's behavior.
    ...
    
    public void layoutContainer(Container parent) {
    		this.xCoordinate = 0;
    		this.yCoordinate = 0;
    
    		this.minimumDimension = new Dimension(0, 0);
    
    		Dimension tmp;
    
    		if (this.scrollable != null) {
    			Dimension scrollableDim = this.scrollable.getPreferredSize();
    			Dimension parentDim = parent.getSize();
    			
    			//whether or not the forward and backward buttons should be painted
    			boolean paintButtons = false;
    
    			if (this.orientation) {
    				if (scrollableDim.width > parentDim.width) {
    					paintButtons = true;
    				}
    			} else {
    				if (scrollableDim.height > parentDim.height) {
    					paintButtons = true;
    				}
    			}
    
    			if (paintButtons) {
    				//paint the backward button
    				if (this.backward != null) {
    					this.backward.setLocation(this.xCoordinate,
    							this.yCoordinate);
    
    					if (this.orientation) {
    						tmp = new Dimension(this.backward.getPreferredSize().width,
    								scrollableDim.height);
    					} else {
    						tmp = new Dimension(scrollableDim.width,
    								this.backward.getPreferredSize().height);
    					}
    					this.backward.setSize(tmp);
    
    
    					if (this.orientation) {
    						this.xCoordinate += tmp.width;
    					} else {
    						this.yCoordinate += tmp.height;
    					}
    
    					this.minimumDimension = new Dimension(tmp.width,
    							tmp.height);
    				}
    
    				int maxWidth = 0;
    				int maxHeight = 0;
    				
    				//paint the forward button
    				if (this.forward != null) {
    					
    					if (this.orientation) {
    						tmp = new Dimension(this.forward.getPreferredSize().width,
    								scrollableDim.height);
    					} else {
    						tmp = new Dimension(scrollableDim.width,
    								this.forward.getPreferredSize().height);
    					}
    					this.forward.setSize(tmp);
    
    					if (this.orientation) {
    						this.forward.setLocation(parentDim.width - tmp.width,
    								this.yCoordinate);
    				
    						maxHeight = (this.minimumDimension.height >= tmp.height)?
    								this.minimumDimension.height : tmp.height;
    						
    						this.minimumDimension = new Dimension(
    								this.minimumDimension.width + tmp.width,
    								maxHeight);
    					} else {
    						this.forward.setLocation(this.xCoordinate,
    								parentDim.height - tmp.height);
    						
    						maxWidth = (this.minimumDimension.width >= tmp.width)?
    								this.minimumDimension.width : tmp.width;
    						
    						this.minimumDimension = new Dimension(maxWidth,
    								this.minimumDimension.height + tmp.height);
    					}
    				}
    
    				this.center.setLocation(this.xCoordinate, this.yCoordinate);
    
    				tmp = scrollableDim;
    				Dimension centerDim;
    				if (this.orientation) {
    					centerDim = new Dimension(parent.getSize().width
    							- this.minimumDimension.width,
    							tmp.getSize().height);
    				} else {
    					centerDim = new Dimension(tmp.getSize().width, 
    							parent.getSize().height - this.minimumDimension.height);
    				}
    				this.center.setSize(centerDim);
    				this.scrollable.setSize(tmp);
    				
    				if (this.orientation) {
    					if (this.scrollable.getPreferredSize().width <=
    						-this.scrollable.getX() + centerDim.width) {
    						
    						this.scrollable.setLocation(
    								centerDim.width - scrollableDim.width,
    								this.scrollable.getY());
    
    						this.forward.setEnabled(false);
    					} else {
    						this.forward.setEnabled(true);
    					}
    				} else {
    					if (this.scrollable.getPreferredSize().height <= 
    						-this.scrollable.getY()	+ centerDim.height) {
    						
    						this.scrollable.setLocation(this.scrollable.getX(),
    										centerDim.height - scrollableDim.height);
    						this.forward.setEnabled(false);
    					} else {
    						this.forward.setEnabled(true);
    					}
    				}
    
    				if (this.scrollable.getLocation().equals(new Point(0, 0))) {
    					this.backward.setEnabled(false);
    				} else {
    					this.backward.setEnabled(true);
    				}
    				
    				if (this.tailing != null) {
    					this.tailing.setSize(0, 0);
    				}
    			} else {
    
    				this.backward.setSize(0, 0);
    				this.forward.setSize(0, 0);
    
    				this.center.setLocation(0, 0);
    				this.scrollable.setLocation(0, 0);
    				
    				if (this.tailing != null) {
    					if (this.orientation) {
    						this.tailing.setSize(parentDim.width - scrollableDim.width, parentDim.height);
    						this.tailing.setLocation(this.scrollable.getX() + scrollableDim.width, this.scrollable.getY());
    						
    					} else {
    						this.tailing.setSize(parentDim.width, parentDim.height - scrollableDim.height);
    						this.tailing.setLocation(this.scrollable.getX(), this.scrollable.getY() + scrollableDim.height);
    					}
    				}
    
    				tmp = scrollableDim;
    				this.center.setSize(tmp);
    				this.scrollable.setSize(tmp);
    			}
    		}
    	}
     
    
  • AppTabBar - the tailing property is removed and in the create method of the CustomScrollPane's property JPanel is added as a tailing panel.
...
public Prop<CustomScrollPane> tabBarScrollPane() {
		class tabBarScrollPane extends ResourceProperty<CustomScrollPane> {

			@Override
			protected CustomScrollPane create() {
				JPanel tailingPanel = new JPanel();
				tailingPanel.setName("appTabBarTrailingPanel");
				CustomScrollPane res = new CustomScrollPane(CustomScrollPane.HORIZONTAL, tailingPanel);
				res.setNames("windowScrollPaneLeftButton", "windowScrollPaneRightButton");
				return res;
			}
...
	}
  • BookDocView - JScrollPane's property is changed to CustomScrollPane. Not much logic is added.
    private Prop<CustomScrollPane> viewOptionsScrollPane() {
    		class ViewOptionsScrollPane extends ResourceProperty<CustomScrollPane> {
    
    			@Override
    			protected CustomScrollPane create() {
    				CustomScrollPane res = new CustomScrollPane(CustomScrollPane.HORIZONTAL, null);
    				res.setNames("windowScrollPaneLeftButton", "windowScrollPaneRightButton");
    				return res;
    			}
    
    			@Override
    			protected void destroy(CustomScrollPane res) {
    				// nothing
    			}
    
    			@Override
    			protected void setup(CustomScrollPane res) {
    				res.setViewportView(bookPanel().get().swingPanel().get());
    				res.swingComponent().validate();
    				res.swingComponent().repaint();
    			}
    
    		}
    		return getBean().makeProp(ViewOptionsScrollPane.class);
    	}
    
  • CustomScrollPane - Method is added in order to be able to change the styling of the scroll bar.
    	/**
    	 * Sets the names of the buttons, for skinning use
    	 * 
    	 * @param backwardName
    	 *            The name for the backward button.
    	 * @param forwardName
    	 *            The name for the forward button.
    	 */
    	public void setNames(String backwardName, String forwardName) {
    		this.backwardArrow.setName(backwardName);
    		this.backwardArrow.setPreferredSize(new Dimension(ICON_WIDTH, ICON_HEIGHT));
    		this.forwardArrow.setName(forwardName);
    		this.forwardArrow.setPreferredSize(new Dimension(ICON_WIDTH, ICON_HEIGHT));
    	}
    
  • lookandfeel_java6.xml - Styling for the separate buttons/icons is added:
    	<!-- ================================= -->
    	<!-- CUSTOM SCROLL PANE LEFT BUTTON -->
    	<!-- ================================= -->
    	<style id="customScrollPaneButtonLeftStyle">
    		<state value="ENABLED">
    			<imagePainter method="buttonBackground" path="/resources/customScrollPane/btnDTBScrollLeft.png"
    				sourceInsets="5 5 5 5" />
    		</state>
    		<state value="FOCUSED">
    			<imagePainter method="buttonBackground" path="/resources/customScrollPane/btnDTBScrollLeft_focused.png"
    				sourceInsets="5 5 5 5" />
    		</state>
    		<state value="PRESSED">
    			<imagePainter method="buttonBackground" path="/resources/customScrollPane/btnDTBScrollLeft_pressed.png"
    				sourceInsets="5 5 5 5" />
    		</state>
    		<state value="MOUSE_OVER">
    			<imagePainter method="buttonBackground" path="/resources/customScrollPane/btnDTBScrollLeft_over.png"
    				sourceInsets="5 5 5 5" />
    		</state>
    		<state value="DISABLED">
    			<imagePainter method="buttonBackground" path="/resources/customScrollPane/btnDTBSScroll_disabled.png"
    				sourceInsets="5 5 5 5" />
    		</state>
    	</style>
    	<!-- Bind buttonStyle to all JButtons -->
    	<bind style="customScrollPaneButtonLeftStyle" type="name" key="customScrollPaneLeftButton" />
    
    	<!-- ================================= -->
    	<!-- CUSTOM SCROLL PANE RIGHT BUTTON -->
    	<!-- ================================= -->
    	<style id="customScrollPaneButtonRightStyle">
    		<state value="ENABLED">
    			<imagePainter method="buttonBackground" path="/resources/customScrollPane/btnDTBScrollRight.png"
    				sourceInsets="5 5 5 5" />
    		</state>
    		<state value="FOCUSED">
    			<imagePainter method="buttonBackground" path="/resources/customScrollPane/btnDTBScrollRight_focused.png"
    				sourceInsets="5 5 5 5" />
    		</state>
    		<state value="PRESSED">
    			<imagePainter method="buttonBackground" path="/resources/customScrollPane/btnDTBScrollRight_pressed.png"
    				sourceInsets="5 5 5 5" />
    		</state>
    		<state value="MOUSE_OVER">
    			<imagePainter method="buttonBackground" path="/resources/customScrollPane/btnDTBScrollRight_over.png"
    				sourceInsets="5 5 5 5" />
    		</state>
    		<state value="DISABLED">
    			<imagePainter method="buttonBackground" path="/resources/customScrollPane/btnDTBSScroll_disabled.png"
    				sourceInsets="5 5 5 5" />
    		</state>
    	</style>
    	<!-- Bind buttonStyle to all JButtons -->
    	<bind style="customScrollPaneButtonRightStyle" type="name" key="customScrollPaneRightButton" />
    
    	<!-- ================================= -->
    	<!-- WINDOW SCROLL PANE LEFT BUTTON -->
    	<!-- ================================= -->
    	<style id="windowScrollPaneButtonLeftStyle">
    		<state value="ENABLED">
    			<imagePainter method="buttonBackground" path="/resources/customScrollPane/btnWBScrollLeft.png"
    				sourceInsets="5 5 5 5" />
    		</state>
    		<state value="FOCUSED">
    			<imagePainter method="buttonBackground" path="/resources/customScrollPane/btnWBScrollLeft_focused.png"
    				sourceInsets="5 5 5 5" />
    		</state>
    		<state value="PRESSED">
    			<imagePainter method="buttonBackground" path="/resources/customScrollPane/btnWBScrollLeft_pressed.png"
    				sourceInsets="5 5 5 5" />
    		</state>
    		<state value="MOUSE_OVER">
    			<imagePainter method="buttonBackground" path="/resources/customScrollPane/btnWBScrollLeft_over.png"
    				sourceInsets="5 5 5 5" />
    		</state>
    		<state value="DISABLED">
    			<imagePainter method="buttonBackground" path="/resources/customScrollPane/btnWBSScroll_disabled.png"
    				sourceInsets="5 5 5 5" />
    		</state>
    	</style>
    	<!-- Bind buttonStyle to all JButtons -->
    	<bind style="windowScrollPaneButtonLeftStyle" type="name" key="windowScrollPaneLeftButton" />
    
    	<!-- ================================= -->
    	<!-- WINDOW SCROLL PANE RIGHT BUTTON -->
    	<!-- ================================= -->
    	<style id="windowScrollPaneButtonRightStyle">
    		<state value="ENABLED">
    			<imagePainter method="buttonBackground" path="/resources/customScrollPane/btnWBScrollRight.png"
    				sourceInsets="5 5 5 5" />
    		</state>
    		<state value="FOCUSED">
    			<imagePainter method="buttonBackground" path="/resources/customScrollPane/btnWBScrollRight_focused.png"
    				sourceInsets="5 5 5 5" />
    		</state>
    		<state value="PRESSED">
    			<imagePainter method="buttonBackground" path="/resources/customScrollPane/btnWBScrollRight_pressed.png"
    				sourceInsets="5 5 5 5" />
    		</state>
    		<state value="MOUSE_OVER">
    			<imagePainter method="buttonBackground" path="/resources/customScrollPane/btnWBScrollRight_over.png"
    				sourceInsets="5 5 5 5" />
    		</state>
    		<state value="DISABLED">
    			<imagePainter method="buttonBackground" path="/resources/customScrollPane/btnWBSScroll_disabled.png"
    				sourceInsets="5 5 5 5" />
    		</state>
    	</style>
    	<!-- Bind buttonStyle to all JButtons -->
    	<bind style="windowScrollPaneButtonRightStyle" type="name" key="windowScrollPaneRightButton" />
    

Changed 15 years ago by stefan

Changed 15 years ago by stefan

Changed 15 years ago by stefan

comment:6 Changed 15 years ago by pap

  • Status changed from s2b_design_finished to s2c_design_ok
  • Design_score changed from 0 to 3
  • Design_reviewers set to pap, meddle, deyan
  • Code related
    • The "tailing" panel should be called "trailing"
    • Don't forget to remove the unnecessary commented out code.
    • Don't forget to change the java5 look and feel xml too.
    • Fix the JavaDoc of the constructor of CustomScrollPane. First it has too much use of the word "used". Second it talks about some application tab bar, that is a totally unknown thing in this module. You should explain what the trailing panel does.
    • When skinning buttons you only changed the horizontally oriented ones but not the vertical.
    • Also you should either set the general look of the CustomScrollPanel for all of its usages (using LaF xml and without exposing methods for skinning) or make methods for setting all the different kinds of buttons and their states and set these for each different use in some setup methods of resource properties with values that you get from the Skin.
  • User experience related.
    • The components in book panel should be centered
    • The focus in book panel should not be changed when clicking buttons
    • Will be good if mouse scroll moves the scrollers (not in analysis however)

comment:7 Changed 15 years ago by stefan

  • Status changed from s2c_design_ok to s3a_implementation_started

comment:8 Changed 15 years ago by stefan

  • Status changed from s3a_implementation_started to s3b_implementation_finished
  • Imp._owners set to stefan
  • Regarding the skinning - I can't agree with you. There are different LaFs because of the special skinning of the application tab bar. I find it pointless only because of that to should make methods for ALL states of ALL buttons.
  • The centering of the components - as I see, they are centered.
  • Focus in the book panel is not changed when clicking the controls.
  • About the mouse scroll. My opinion is that this should be part of another ticket - maybe next review of the custom scroll pane.

Changed 15 years ago by stefan

Changed 15 years ago by stefan

comment:9 Changed 15 years ago by pap

  • Status changed from s3b_implementation_finished to s3c_implementation_ok
  • Imp._score changed from 0 to 3
  • Imp._reviewers set to deyan, pap
  • Commited to trunk in [9163].
  • Visually it is ok.
  • The code of the AppTabBar has become even more messy.

comment:10 Changed 13 years ago by meddle

  • Status changed from s3c_implementation_ok to closed
  • Resolution set to obsolete

Closing all the tickets before M Y1

Note: See TracTickets for help on using tickets.