65.9K
CodeProject 正在变化。 阅读更多。
Home

TMDock - Dockbar 样本 Alpha 混合

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.97/5 (20投票s)

2013 年 1 月 31 日

CPOL

2分钟阅读

viewsIcon

44617

downloadIcon

2725

停靠栏样本,展示了许多 Alpha 混合函数。

引言

这是我对停靠栏主题的贡献。该项目从 Xdock 项目开始,并添加了一些有用的功能,例如标签、将停靠栏放置在顶部或底部、透明度等。还有很多工作要做,但我认为这是一个良好的开端。

背景

请参考 XDock 项目

新增功能

新增功能

  • 停靠栏居中显示在屏幕上,并调整大小以适应其内容。
  • 停靠栏可以定位在屏幕的顶部或底部。
  • 当鼠标进入图标时,有放大效果。
  • 当鼠标离开图标时,有缩小效果。
  • 当前图标被突出显示。
  • 每个图标都有一个可自定义的工具提示。
  • 您可以使停靠栏和图标完全透明。
  • 您可以自定义停靠栏的某些方面。
  • 工具提示完全可自定义
    • 背景开启 / 关闭  
    • 边框有 / 无
    • 带圆角有 / 无 
    • 文字 3D 效果 
    • 文字阴影效果 
    • 文字字体 
    • 文字字体大小 
    • 文字效果,粗体、斜体等。
    • 文字颜色 
    • 背景颜色,纯色或渐变以及透明度级别

这是标签设置表单

这里有一些完全透明的停靠栏样本

关注点

使用透明对象的问题是您会丢失鼠标移动事件。

我通过为停靠栏和图标绘制一个假的背景来解决这个问题。以下代码对停靠栏有效。 

' for fake background
Dim bmp As Bitmap
Dim iaFake As New Imaging.ImageAttributes
Dim cmFake As New Imaging.ColorMatrix
cmFake.Matrix33 = 0.5 / 100.0F
iaFake.SetColorMatrix(cmFake)  
...
' build fake backgrround
bmp = New Bitmap(CInt(pWidth), CInt(pHeight))
grFake = Graphics.FromImage(bmp)
grFake.FillRectangle(New SolidBrush(Color.Silver), New Rectangle(0, 0, bmp.Width, bmp.Height))
' paint fake background
gr.DrawImage(bmp, _
                   New Rectangle(posX, _
                                          posY, _
                                          bmp.Width, _
                                          bmp.Height), _
                   0, 0, bmp.Width, bmp.Height, _
                   GraphicsUnit.Pixel, _
                   iaFake)

另一个我开发的有趣点是与图标相关的文字显示。这由 DockManager 类中的 PaintLabel 方法确保。

Private Sub PaintLabel(ByRef DstGraphics As Graphics, _
                       ByVal DockSettings As Settings, _
                       ByVal pDockItem As IDockItem)
    Dim ScreenWidth As Integer = Screen.PrimaryScreen.WorkingArea.Width
    Dim borderWidth As Integer = DockSettings.Labels.BorderLabelFrameWidth
    Dim topLeft As Integer

    ' Create string to draw.
    Dim drawString As [String] = pDockItem.Name
    Dim szF As SizeF
    Try
        szF = DstGraphics.MeasureString(drawString, New Font(DockSettings.Labels.FontName, _
                                                             DockSettings.Labels.FontSize, _
                                                             DockSettings.Labels.FontStyle, _
                                                             GraphicsUnit.Point))
    Catch ex As Exception
        Trace.WriteLine(ex.ToString)
    End Try
    Dim sz As New Size(szF.Width, szF.Height)
    'compute origin of the label
    Dim labelX As Integer = borderWidth + pDockItem.X + (pDockItem.Width - sz.Width) / 2
    ' check if is outside on left
    If labelX < borderWidth * 2 Then
        labelX = borderWidth * 2
    End If

    Select Case DockSettings.Position.ScreenPosition
        Case cPosition.ScreenPos.Top
            ' follow the item height
            'topLeft = pDockItem.Y + pDockItem.Height + DockSettings.Labels.TopMargin - frm.Top
            ' fixed
            topLeft = pDockItem.Y + IIf(DockSettings.Behavior.AnimatedIcons, DockSettings.Icons.ZoomPx, _
              pDockItem.Height) + DockSettings.Labels.TopMargin - frm.Top
        Case cPosition.ScreenPos.Bottom
            ' follow the item height
            'topLeft = pDockItem.Y - DockSettings.Labels.TopMargin - sz.Height - frm.Top
            ' fixed
            topLeft = pDockItem.Y + IIf(DockSettings.Behavior.AnimatedIcons, pDockItem.Height, 0) - _
              IIf(DockSettings.Behavior.AnimatedIcons, DockSettings.Icons.ZoomPx, 0) - _
                    DockSettings.Labels.TopMargin - sz.Height - frm.Top
        Case cPosition.ScreenPos.Left
        Case cPosition.ScreenPos.Right
        Case Else
            Throw New Exception("PaintLabel: Screen position unknown")
    End Select

    ' setup the destination area
    Dim rectOrig As New Rectangle(labelX, _
                                  topLeft,
                                  sz.Width + borderWidth, _
                                  sz.Height + borderWidth)

    ' draw frame with border
    If DockSettings.Labels.FrameRoundedCorners Then
        DrawRoundedFrame(DstGraphics, _
                         DockSettings, _
                         rectOrig, _
                         DockSettings.Labels.FrameRadius, _
                         borderWidth)
    Else
        DrawRectangleFrame(DstGraphics, _
                           DockSettings, _
                           rectOrig, _
                           borderWidth)
    End If

    ' paint the label
    DrawLabel(DstGraphics, _
              rectOrig, _
              DockSettings, _
              pDockItem)
End Sub

PaintLabel 首先计算标签大小,然后计算其相对位置。然后有三个有趣的子程序

  • DrawRectangleFrame
  • DrawRoundedFrame 
  • DrawLabel  

气泡效果DockManager 类的 UpdateAllItems 方法中。气泡效果根据图标中心与鼠标光标的距离计算图标的大小,距离越小,图标越大。 

distance = (pMax / 2 * m_Settings.Icons.ZoomWidth)
fConv = (pMax - m_Settings.Icons.SizePx) / distance
...
gap = X - pDockItem.CentreX
...
pZoom = m_Settings.Icons.SizePx + fConv * (distance - Math.Abs(gap))

其中 pMax 是允许的最大尺寸,Zoomwidth 是我们想要的气泡效果距离,而 SizePx 是图标大小。 

后续步骤

  • 完全拖放新应用程序。
  • 启用拖动图标从停靠栏中删除图标。
  • 管理特殊应用程序,例如回收站。
  • 在鼠标悬停在图标上时添加更多效果。 
  • 还有什么?
© . All rights reserved.