コード例 #1
0
        internal void SetSelectionStartItem(Point p)
        {
            //清除其他的选择状态
            this.Clear();

            MessageListItem item = _owner.GetItemAtPosition(p) as MessageListItem;

            if (item == null)
            {
                return;
            }

            //设定文本选中
            if (item.Message.Type == MessageType.Text)
            {
                this._selectingTextItem = item;
                Rectangle rect = item.Bounds;

                for (int i = 0; i < this._selectingTextItem.DrawingObjects.Count; i++)
                {
                    DrawingObject dobj = item.DrawingObjects[i];
                    if (dobj.Type == DrawingObjectType.TextBlock)
                    {
                        Rectangle bounds = dobj.Offset(rect.X, rect.Y);

                        if (bounds.Contains(p))
                        {
                            TextBlockObj tb = dobj.Tag as TextBlockObj;
                            StringPart   sp = tb.StringPart;
                            using (Graphics g = _owner.CreateGraphics())
                            {
                                tb.SelectionStart        = StringMeasurer.GetCharIndex(g, sp.Font, p.X - (int)dobj.X, sp.String);
                                this._selectStartDoIndex = i;
                                break;
                            }
                        }
                    }
                }
            }
        }
コード例 #2
0
 public TextBlockObj(StringPart sp)
 {
     this.StringPart = sp;
     ClearSelection();
 }
コード例 #3
0
        public static List <StringPart> Measure(Graphics g, Font font, int width, string str)
        {
            List <StringPart> spList = new List <StringPart>(16);

            int    pos = 0;
            int    x = 0, y = 0, w = 0, h = font.Height;
            string cutStr    = "";
            bool   cFlag     = false;
            bool   cWrapFlag = false;

            for (int i = 0; i < str.Length;)
            {
                cWrapFlag = false;
                if (i == str.Length - 1)
                {
                    w     += GetCharWidth(str[i], g, font);
                    cutStr = str.Substring(pos, i - pos + 1);
                    cFlag  = true;
                    i++;
                }
                else if (str[i] == '\r')
                {
                    cutStr = str.Substring(pos, i - pos);
                    if (i + 1 < str.Length)
                    {
                        //\r\n
                        i += 2;
                    }
                    else
                    {
                        i++;
                    }
                    cFlag = true;
                }
                else if (str[i] == '\n')
                {
                    cutStr = str.Substring(pos, i - pos);
                    i++;
                    cFlag = true;
                }
                else
                {
                    w += GetCharWidth(str[i], g, font);
                    if (w > width)
                    {
                        cutStr    = str.Substring(pos, i - pos);
                        cFlag     = true;
                        cWrapFlag = true;
                    }
                    else
                    {
                        cFlag = false;
                    }
                }

                if (cFlag)
                {
                    StringPart sp = new StringPart
                    {
                        Bounds          = new Rectangle(x, y, w, h),
                        String          = cutStr,
                        TextFormatFlags = TextFormatFlags,
                        Font            = font,
                        Wrap            = cWrapFlag,
                    };

                    spList.Add(sp);

                    pos = i;
                    y  += h; w = 0;
                }
                else
                {
                    i++;
                }
            }

            return(spList);
        }
コード例 #4
0
        protected override void OnDrawItem(UI.DrawItemEventArgs args)
        {
            MessageListItem item = args.Item as MessageListItem;
            Message         m    = item.Message;

            args.DrawBackground();

            Graphics g = args.Graphics;

            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            Rectangle rect = item.Bounds;

            Rectangle drawingObjRect;
            Point     pos = PointToClient(MousePosition);

            foreach (DrawingObject dobj in item.DrawingObjects)
            {
                drawingObjRect = dobj.Offset(rect.X, rect.Y);

                switch (dobj.Type)
                {
                //头像
                case DrawingObjectType.ProfilePhoto:
                {
                    g.DrawImage(ProfilePhotoPool.GetPhoto(item.User.ID), drawingObjRect);

                    if (drawingObjRect.Contains(pos))
                    {
                        g.DrawRectangle(IMAGE_BORDER_PEN_FOCUS, drawingObjRect.X, drawingObjRect.Y, drawingObjRect.Width, drawingObjRect.Height);
                    }
                    break;
                }

                //时间, 昵称,状态
                case DrawingObjectType.Title:
                {
                    string text = item.User.NickName + "  " + m.Time.ToString("yyyy/MM/dd HH:mm:ss");
                    if (!m.Flag)
                    {
                        text += "  传送失败";
                    }
                    TextRenderer.DrawText(g, text,
                                          args.Font, new Point((int)drawingObjRect.X, (int)drawingObjRect.Y)
                                          , m.Flag ? SUCCESS_TITLE_COLOR : ERROR_TITLE_COLOR, TextFormatFlags.Left);
                    break;
                }

                //文本消息
                case DrawingObjectType.TextBlock:
                {
                    TextBlockObj tb       = dobj.Tag as TextBlockObj;
                    StringPart   sp       = tb.StringPart;
                    int          selStart = Math.Min(tb.SelectionStart, tb.SelectionEnd);
                    int          selEnd   = Math.Max(tb.SelectionStart, tb.SelectionEnd);

                    string str1 = selStart == -1 ? sp.String : sp.String.Substring(0, selStart);
                    string str2 = selStart == -1 ? "" : sp.String.Substring(selStart, tb.SelectionLength);
                    string str3 = selEnd == -1 ? "" : sp.String.Substring(selEnd + 1);

                    //选择前的文本
                    if (!string.IsNullOrEmpty(str1))
                    {
                        TextRenderer.DrawText(g, str1, sp.Font, new Point((int)drawingObjRect.X, (int)drawingObjRect.Y), args.ForeColor,
                                              StringMeasurer.TextFormatFlags);
                    }

                    //选择中文本
                    if (!string.IsNullOrEmpty(str2))
                    {
                        int w1 = StringMeasurer.Width(g, sp.Font, str1, sp.TextFormatFlags);
                        int w2 = StringMeasurer.Width(g, sp.Font, str2, sp.TextFormatFlags);
                        drawingObjRect.X    += w1;
                        drawingObjRect.Width = w2;

                        g.FillRectangle(BrushPool.GetBrush(TEXT_SELECTION_BACK_COLOR), drawingObjRect);
                        TextRenderer.DrawText(g, str2, sp.Font, new Point((int)drawingObjRect.X, (int)drawingObjRect.Y),
                                              TEXT_SELECTION_FORE_COLOR, StringMeasurer.TextFormatFlags);

                        //选择后的文本
                        if (!string.IsNullOrEmpty(str3))
                        {
                            drawingObjRect.X    += w2;
                            drawingObjRect.Width = dobj.Width - w1 - w2;
                            TextRenderer.DrawText(g, str3, sp.Font, new Point((int)drawingObjRect.X, (int)drawingObjRect.Y), args.ForeColor,
                                                  StringMeasurer.TextFormatFlags);
                        }
                    }
                    break;
                }

                case DrawingObjectType.Image:
                {
                    Image image = (m as ImageMessage).Image;
                    g.DrawImage(image, drawingObjRect);

                    if (drawingObjRect.Contains(pos))
                    {
                        g.DrawRectangle(IMAGE_BORDER_PEN_FOCUS, drawingObjRect.X, drawingObjRect.Y, drawingObjRect.Width, drawingObjRect.Height);
                    }
                    else
                    {
                        g.DrawRectangle(IMAGE_BORDER_PEN, drawingObjRect.X, drawingObjRect.Y, drawingObjRect.Width, drawingObjRect.Height);
                    }
                    break;
                }

                case DrawingObjectType.File:
                {
                    FileMessage fm = m as FileMessage;

                    //底背景
                    g.FillRectangle(Brushes.White, drawingObjRect);
                    if (drawingObjRect.Contains(pos))
                    {
                        g.DrawRectangle(IMAGE_BORDER_PEN_FOCUS, drawingObjRect.X, drawingObjRect.Y, drawingObjRect.Width, drawingObjRect.Height);
                    }
                    else
                    {
                        g.DrawRectangle(IMAGE_BORDER_PEN, drawingObjRect.X, drawingObjRect.Y, drawingObjRect.Width, drawingObjRect.Height);
                    }

                    //文件名,文件大小,ICON
                    Image image       = FileIconPool.GetIcon(fm.OriginFilePath);
                    int   imageWidth  = 64;
                    int   imageHeight = 64 * image.Height / image.Width;

                    Rectangle imageRect    = new Rectangle(drawingObjRect.X + FILE_SEND_WIDTH - imageWidth - MARGIN, drawingObjRect.Y + MARGIN, imageWidth, FILE_SEND_HEIGHT - Font.Height - MARGIN * 3);
                    Rectangle fileNameRect = new Rectangle(drawingObjRect.X + MARGIN, drawingObjRect.Y + MARGIN, FILE_SEND_WIDTH - imageWidth - MARGIN * 3, FILE_SEND_HEIGHT - Font.Height - MARGIN * 3);
                    Rectangle fontRect     = new Rectangle(drawingObjRect.X + MARGIN, drawingObjRect.Y + FILE_SEND_HEIGHT - Font.Height - MARGIN, FILE_SEND_WIDTH - MARGIN * 2, Font.Height);
                    Rectangle pieRect      = new Rectangle(drawingObjRect.X + (FILE_SEND_WIDTH - PROGRESS_PIE_D) / 2, drawingObjRect.Y + (FILE_SEND_HEIGHT - PROGRESS_PIE_D) / 2, PROGRESS_PIE_D, PROGRESS_PIE_D);
                    Rectangle processRect  = new Rectangle(drawingObjRect.X, drawingObjRect.Y + (FILE_SEND_HEIGHT - Font.Height * 2) / 2, FILE_SEND_WIDTH, Font.Height * 2);

                    //当文件名超过显示部分时,中间用省略号表示
                    string str = fm.FileName;
                    SizeF  s   = g.MeasureString(fm.FileName, Font, new System.Drawing.SizeF((float)fileNameRect.Width, (float)fileNameRect.Height), StringFormat.GenericDefault, out int count, out int lines);
                    if (s.Height >= fileNameRect.Height & str.Length >= count)
                    {
                        //由于会出现半行的情况,直接写死了所取的字符串数目
                        str = str.Substring(0, 36) + "・・・" + str.Substring(str.Length - 4);
                    }
                    g.DrawImage(image, imageRect.X, imageRect.Y, imageWidth, imageHeight);
                    g.DrawString(str, args.Font, Brushes.Black, fileNameRect);
                    TextRenderer.DrawText(g, LanFile.HumanReadbleLen(fm.FileLength), args.Font, fontRect, Color.FromArgb(0, 0, 0), TextFormatFlags.Left);

                    if (item.State == MessageState.Receiving ||
                        item.State == MessageState.Sending)
                    {
                        //接受进度
                        g.FillRectangle(MESSAGELIST_PROGRESS_BACKGROUND_BRUSH, drawingObjRect);

                        g.DrawPie(PROGRESS_PEN, pieRect, 0, 360);
                        g.FillPie(MESSAGELIST_PROGRESS_FILLED_BRUSH, pieRect, 0, 360 * item.Progress / 100);

                        //TODO 显示剩余时间,传输速度
                        TextRenderer.DrawText(g, item.Progress + "%" + "\r\n" + LanFile.HumanReadbleLen(item.FileTransportedLength) + "/" + LanFile.HumanReadbleLen(fm.FileLength),
                                              args.Font, processRect, Color.FromArgb(0, 0, 0), TextFormatFlags.HorizontalCenter);
                    }
                    break;
                }
                }
            }
        }
コード例 #5
0
        internal void SetSelectionEndItem(Point location)
        {
            if (!this.HasSelection)
            {
                return;
            }

            MessageListItem hoverItem = _owner.GetItemAtPosition(location) as MessageListItem;

            if (hoverItem == null)
            {
                //鼠标移动到其他地方了,算了,不选了
                this.Clear();
                return;
            }

            if (hoverItem != this._selectingTextItem)
            {
                //当前的选择的不是上面一个
                this.Clear();
                return;
            }

            Rectangle rect = this._selectingTextItem.Bounds;

            for (int i = 0; i < this._selectingTextItem.DrawingObjects.Count; i++)
            {
                DrawingObject dobj = this._selectingTextItem.DrawingObjects[i];

                if (dobj.Type == DrawingObjectType.TextBlock)
                {
                    Rectangle    bounds = dobj.Offset(rect.X, rect.Y);
                    TextBlockObj tb     = dobj.Tag as TextBlockObj;

                    if (bounds.Contains(location))
                    {
                        StringPart sp = tb.StringPart;
                        using (Graphics g = _owner.CreateGraphics())
                        {
                            tb.SelectionEnd        = StringMeasurer.GetCharIndex(g, sp.Font, location.X - (int)dobj.X, sp.String);
                            this._selectEndDoIndex = i;
                            break;
                        }
                    }
                }
            }

            //开始与结束直接的所有TextBlock都设定为全选中
            int startIndex = Math.Min(this._selectStartDoIndex, this._selectEndDoIndex);
            int endIndex   = Math.Max(this._selectStartDoIndex, this._selectEndDoIndex);

            List <TextBlockObj> selObj = new List <TextBlockObj>();

            for (int i = startIndex; i <= endIndex; i++)
            {
                DrawingObject dobj = this._selectingTextItem.DrawingObjects[i];
                if (dobj.Type == DrawingObjectType.TextBlock)
                {
                    TextBlockObj tbObj = dobj.Tag as TextBlockObj;

                    if (this._selectStartDoIndex < this._selectEndDoIndex)
                    {
                        //从上往下选择时
                        if (i == this._selectStartDoIndex)
                        {
                            tbObj.SelectionEnd = tbObj.Length - 1;
                        }
                        else if (i == this._selectEndDoIndex)
                        {
                            tbObj.SelectionStart = 0;
                        }
                    }
                    else if (this._selectStartDoIndex > this._selectEndDoIndex)
                    {
                        //从下往上选择时
                        if (i == this._selectStartDoIndex)
                        {
                            tbObj.SelectionEnd = 0;
                        }
                        else if (i == this._selectEndDoIndex)
                        {
                            tbObj.SelectionStart = tbObj.Length - 1;
                        }
                    }
                    if (i != this._selectStartDoIndex && i != this._selectEndDoIndex)
                    {
                        tbObj.SelectAll();
                    }

                    selObj.Add(tbObj);
                    this._prevSelection.Remove(tbObj);
                }
            }

            //清除选择
            foreach (TextBlockObj item in this._prevSelection)
            {
                item.ClearSelection();
            }
            this._prevSelection = selObj;
        }